Upon seeing the Fluxiom intro video, I was compelled to figure out how they pulled off iPhoto-like image scaling in a browser. Leveraging the work of others, it’s actually very simple.
If you use the script.aculo.us slider control to capture input values, it’s really just a matter of converting those values into something useful and modifying styles.
Note: OS X folks using Firefox will likely get some stutter, due to a crippling, 3 year old bug.
A simple demo.







Here’s how.
1. Install and reference the Prototype and script.aculo.us libraries.
2. Create the track and slider HTML nodes. (CSS inline for simplification)
<div id=”handle1″ style=”width: 18px; height: 18px;”>
<img src=”/images/content/blog/scaler_slider.gif”/>
</div>
</div>
3. Create a function to be called when the slider value changes. This collects all nodes for resizing, remaps the 0-1 scale to a definable range, and then scales.
var scalePhotos = document.getElementsByClassName(’scale-image’);
floorSize = .26;
ceilingSize = 1.0;
v = floorSize + (v * (ceilingSize - floorSize));
for (i=0; i < scalePhotos.length; i++) {
scalePhotos[i].style.width = (v*190)+’px’;
}
}
4. Create the slider and map the two events to our function (either inline, or as part of the body onload event). See the Slider docs for usage details.
{axis:’horizontal’, minimum: 0, maximum:200, alignX: 2, increment: 2, sliderValue: 1});
demoSlider.options.onSlide = function(value){
scaleIt(value);
}
demoSlider.options.onChange = function(value){
scaleIt(value);
}
5. Finally, create the HTML for our images.
<div class=”scale-image” style=”width: 190px; padding: 10px; float: left;”>
<img src=”/images/content/blog/scaler_1.jpg” width=”100%”/>
</div>
<div class=”scale-image” style=”width: 190px; padding: 10px; float: left;”>
<img src=”/images/content/blog/scaler_2.jpg” width=”100%”/>
</div>
</div>
There are definitely some areas to clean up (redundant div width specifications, for example), but for a quick demo it will suffice. Tested with Firefox, Safari and Win IE 6.
Update: There appears to be a small issue in IE; the slider disappears when you start dragging.
Update: Fixed. Moved the handle image to an actual img.
Update: Corrected a typo. (Fluxium != Fluxiom)


December 9th, 2005 at 12:24 pm
John this tutorial on something I’ve been dying to figure out myself. Thanks for sharing!
December 9th, 2005 at 12:30 pm
Nice work, I can’t wait to start playing with this :).
December 9th, 2005 at 12:33 pm
The resize stutters for me in firefox. I am running XP on a AMD XP 2000+.
December 9th, 2005 at 12:52 pm
I’m sure we’ll start seeing this a lot. Personally, I’m trying to think of where I could use it…
December 9th, 2005 at 1:00 pm
badass, i’m going to start using this hopefully. i just wish i didn’t have to find and replace all of the funky quotes ( ” ) haha
December 9th, 2005 at 1:01 pm
This was initially created as part of a photo blog admin interface. The slider allows me to see a small subset of images in detail, or scale them down to see the full list of posts. I initially figured it would just be a novel experiment, but I’ve found it to be pretty useful. The full admin app also scales blog post text by calculating “em” sizes based on the slider value.
The scaling quality at smaller sizes is suspect, but at that zoom level I’m not too concerned with fidelity.
December 9th, 2005 at 1:13 pm
Thanks for sharing. I’m going to add this to my site.
December 9th, 2005 at 1:55 pm
Works fine for me on a P4 - Firefox 1.5 full release. Silky smooth, Intel chipset graphics (no hot-shot graphics card here).
Suggestion - extend this to dynamically change images with small byte size thumbnails initially, swapping out to larger images as scaling reaches a certain threshold with background image loading (after the thumbnails) for quick response
Yes, I’ll work on that if you don’t (assuming I have time someday during the holiday break…)
December 9th, 2005 at 2:04 pm
No really new, it’s the same mechanism for DnD, just that you’re forcing the image to be automatically re-rendered to a different size. We did something similar for moving images over buttons (enter events). Still, it’s a great example showing the potential for web apps capable of fat client behavior.
December 9th, 2005 at 3:12 pm
oh wonderful idea. thank you for sharing!
December 9th, 2005 at 3:13 pm
This is a great trick, but how would you do it with a mix of horizontal and vertical images? The vertical ones scale to 100% width, which throws off the grid. The script needs to recognize that vertical images shouldn’t scale beyond 100% of the horizontal.
December 9th, 2005 at 3:46 pm
Doesn’t work for me under FireFox 1.5 (but IE). What happens under FireFox for me, is that the image width is simply cropped, but the image isn’t scaled. Looking at the code, that actually makes sense. The containing div-element is cropped, why should that affect the *scaling* of the contained image? I guess, the width of the actual image should be change in order to work consistently, right?
December 9th, 2005 at 4:06 pm
Jan: FF1.5 works fine for me, not sure what the difference is. My understanding is that by specifying width=”100%” in the img tag, the image will scale to fill its parent.
Yeah, changing the images directly also works (not sure if it would fix the FF issue you’re seeing), it was just an arbitrary decision to wrap them in this case.
Steve: Agreed that logic needs to be added to constrain tall images.
December 9th, 2005 at 4:10 pm
been there, done that, but your slider is smoother under IE than I managed to do. (stupid thing always wanted clicks, rather than drags, and was INSANELY slow for large numbers of images)
Here’s another thought to add: use a cookie to store the position of the slider where the user last felt he had a “comfortable size”.
It took me too long to figure out how to do (debug) all of the features I wanted, & I wandered on to other projects before I got around to re-doing my whole site that way… probably a good thing, I was too addicted to liquid layouts at the time, my distaste for rectangular, grid-like layouts caused me to make something REALLY ugly.
December 9th, 2005 at 4:16 pm
Here’s the solution I came up with (and it works in FF1.5 and IE):
images = getElementsByClassName(document,’scale-image’);
for(var i = 0; i
December 9th, 2005 at 4:18 pm
Damn, it didn’t seem to post right. Here we go again:
images = getElementsByClassName(document,'scale-image');
for(var i = 0; i
December 9th, 2005 at 4:24 pm
Ah, it’s the less equal sign:
images = getElementsByClassName(document,’scale-image’);
for(var i = 0; i LE images.length; i++) {
var image = images[i].getElementsByTagName( ‘img’ );
image[0].style.width = (v*190)+’px’;
image[0].style.height = ‘auto’;
}
December 9th, 2005 at 4:44 pm
Congratulations.. just don’t merge my account with Yahoo! like Flickr was forced to do!
December 9th, 2005 at 4:44 pm
This is really nice, work for me in FF 1.5 and IE6. Thanks for posting the code.
December 9th, 2005 at 6:27 pm
Here’s a quick optimization for this code… just make the “scalePhotos” array global, then only call “getElementsByClassName” if it’s null… such as this:
…
var scalePhotos;
function scaleIt(v) {
if(scalePhotos == null){scalePhotos = document.getElementsByClassName(”scale-image”);}
…
This should make it run a little smoother, instead of calling that function every time the slider moves.
December 9th, 2005 at 7:21 pm
Hi,
I created aa test file http://suncafe.us/windchilltest/test1.html
it doesn’t work. what am I doing wrong
scaler.js :
function scaleIt(v) {
var scalePhotos = document.getElementsByClassName(”scale-image”);
// Remap the 0-1 scale to fit the desired range
floorSize = .26;
ceilingSize = 1.0;
v = floorSize + (v * (ceilingSize - floorSize));
for (i=0; i
December 9th, 2005 at 7:36 pm
Alain: It looks like you need to download and include the Prototype and scriptaculous libraries. See the first step for links to these files.
December 9th, 2005 at 9:52 pm
Was the script above meant to solve the vertical image problem? If so, I can’t seem to make it work. And, I replaced “LE” with “[=” (with the open bracket being the less than sign so as not to break the markup). Is this snippet supposed to replace a portion of the original script, or just added on?
December 9th, 2005 at 10:09 pm
Thanks for the great technique.
I’ve given it a try. In firefox there are some funny line breaks mixed in with the images, although in IE everything works as it should. I think that the problem has to do with “float: left;” but I’m having a hell of a time trying to fix it. If anyone familiar with firefox and floating with css would take a look, I’d be much obliged.
http://www.bajilives.com
December 9th, 2005 at 10:12 pm
Whoops, that link should be:
http://www.bajilives.com/test.html
December 10th, 2005 at 5:15 am
thanks
December 10th, 2005 at 5:39 pm
I did this a few months back using some Walter Zorn magic, plus some ImageMagick stuff on the back side in Zope to actually save the images.
check out http://walterzorn.com
I actually implemented a solution where you could hold-and-drag the corners and resize that way, but I suppose the slider is nice too.
Walter Zorn is a JavaScript GOD.
December 10th, 2005 at 7:02 pm
I’ve done a test page but I’d really like it to load with the pictures zoomed all the way out. Jeremy A, you seem to have accomplished this, but I can’t figure out how. Any advice?
December 10th, 2005 at 7:03 pm
Damn… wrong link…
Try this one.
December 11th, 2005 at 2:25 am
All right… after a lot of tinkering I’ve managed to get it so that the page loads with the pictures zoomed all the way out. See here. My next problem is that while zooming in, the images jump around a bit. (Looks like this. In the original demo on this page the images flow much more smoothly. Anyone know how to fix that?
December 11th, 2005 at 3:49 am
Very nice, thanks for sharing
December 11th, 2005 at 5:47 pm
leifm
You should set the width to 450 in the css inside the scale-image.
December 12th, 2005 at 2:04 am
Fantastic ! Thanks for give us those tips
December 12th, 2005 at 11:27 am
Nice trick, grat.
December 12th, 2005 at 1:27 pm
jof:
You should set the width to 450 in the css inside the scale-image.
Thanks for the idea. Unfortunately, I tried that and it doesn’t seem to make much difference. See here. It still has the same gaps when zooming in on the images. Any other ideas?
December 12th, 2005 at 5:12 pm
leifm —
I had the same problem as you and it took me a long time to figure out the problem. Fortunately there is a very easy and intuitive fix. You are really dealing with a list of images here, not a whole mass of divs. So why not hold the pictures in a list? It solved all my problems. For a full example, check out:
http://www.bajilives.com/galleries/Mazatlan/index.html
Look at the page source and the css.
Best of luck.
December 12th, 2005 at 6:01 pm
OK, trying this again with escaped < and >….
Hi leifm. Your problems are happening because not all your images are the same size. Image #3 is one pixel shorter than the rest. Image #7 is one pixel taller. As the images scale, there can be times when that one extra pixel difference allows a single image to start off in that 1 pixel gap while everything else is forced to start on the next row (which is now much farther down).
The solution (short of making all your images the same size) is to specify a height for the <div>’s as well, such as:
<div class=”scale-image” style=”padding: 10px; float: left; width: 300px; height: 200px;”>
You will also need to adjust this div height in the JS when you adjust the slider. Thus the scaleIt() function becomes:
function scaleIt(v) {
if(scalePhotos == null){scalePhotos = document.getElementsByClassName(’scale-image’);}
floorSize = .226;
ceilingSize = 1.0;
v = floorSize + (v * (ceilingSize - floorSize));
for (i=0; i < scalePhotos.length; i++) {
scalePhotos[i].style.width = (v*450)+’px’;
scalePhotos[i].style.height = (v*300)+’px’;
}
}
Note that this assumes a 3:2 width to height ratio. The numbers would need to be adjusted for images with a different aspect ratio.
Finally, this is 1/2 of the way to allowing vertical images. But for the rest of it you’ll have to wait just a little bit longer.
December 13th, 2005 at 1:34 am
Jeremy A:
You are really dealing with a list of images here, not a whole mass of divs. So why not hold the pictures in a list? It solved all my problems.
I get the feeling that keeping all the images in their own seperate divs is going to be integral to the integration of vertically-oriented images. I like the way that you got around this issue on your site. Unfortunately, I just don’t think square images would work for me; I’m much too hooked on the 2:3 (or 3:2) ratio.
Josh Weihnacht:
Your problems are happening because not all your images are the same size.
Thank you so much for this! I wouldn’t have even thought to check that. After resizing the images, everything works much more smoothly.
Note that this assumes a 3:2 width to height ratio. The numbers would need to be adjusted for images with a different aspect ratio.
I can kind of see where you’re going with this, but I don’t have the Java skills to go there myself.
Finally, this is 1/2 of the way to allowing vertical images. But for the rest of it you’ll have to wait just a little bit longer.
You can count on it! I really like this method of displaying a gallery of images. I’ll check back regularly to see what you’ve come up with.
Thanks.
December 13th, 2005 at 1:36 am
Oh, and if anyone wants to see what a gallery of vertically-oriented images looks like using this slider method, I put one up here”.
December 13th, 2005 at 8:41 am
Similar to what drafnas said, but saving the starting image width and using a closure instead of a global to store the array of images
function makeScaler(className) {
var scalePhotos = document.getElementsByClassName(className);
var photos=[]
for (var i=0; i < scalePhotos.length; i++){
// horrible, ugly, works
im=scalePhotos[i].getElementsByTagName(’img’)[0]
var thisPhoto=[scalePhotos[i],im.width,im.height]
photos[i]=thisPhoto
}
return function (v) {
floorSize = .26;
ceilingSize = 1.0;
v = floorSize + (v * (ceilingSize - floorSize));
for (var i=0; i < photos.length; i++) {
photos[i][0].style.width = (v*photos[i][1])+”px”;
}
}
}
scaleIt=makeScaler(”scale-image”)
Needs some cleanups and I guess the closure can be scary, but it has the advantage of not needing the image width specified in the html source and works fine with a mix of horizontal and vertical images. To be clear, it works fine if the image size is specified in the source, it just doesn’t need it.
December 13th, 2005 at 9:15 am
leifm - the point of “allowing” vertical images is in a mix of horizontal and vertical images (in fact, it should allow for various sizes, regardless of orientation). Your demo is all vertical images, which is how the current system works anyway.
December 13th, 2005 at 9:06 pm
Another fun little image resizing variation to play with:
http://www.nsftools.com/tips/ImageResize.htm
December 13th, 2005 at 11:38 pm
Best solution I see is to use the native width as the basis for sizing. One way of doing this is to store the width in the id tag of th image and call it in script like so.
scalePhotos[i].style.width = (v*scalePhotos[i].id)+”px”;
no arrays or anything this is the only change to the original code provided in the article, well I did away with the divs around the images like so
well this works great for me.
December 13th, 2005 at 11:46 pm
Applied in a Zenphoto theme with gradual image loading based on size.
Thanks a lot for this, it’s very cool.
December 14th, 2005 at 10:28 am
Very cool stuff Tristan.
December 15th, 2005 at 5:27 am
Cool! and thanks.
/t
December 16th, 2005 at 11:39 am
Thanks for sharing the article - gives me something fun to play with for a while!
I have a problem, though… For some reason I cannot get my slider to go all the way to the right. It’s bound to be something very easy, but I just can’t spot it this late into the week.
Can anyone check it out and spot the problem?
http://www.sussex.ac.uk/USIS/test/andy/web2/examples/slider/
December 18th, 2005 at 7:23 pm
Hi Andy,
It looks like the version of slider.js that you have is a little different than the one that is used in this demo. That seems to be the source of the problem. However, if you tweak your settings for the slider, you can adapt. Change your “alignX” parameter to -5 so that the function call looks like this and things should work correctly for you.
demoSlider = new Control.Slider(’slider-handle’, ’slider-bar’, {
axis:’horizontal’, minimum: 0, maximum: 200, alignX: -5, increment: 2, sliderValue: 0.5
});
December 19th, 2005 at 3:57 am
You’re a star, Josh! Many thanks for your help — it worked perfectly!
December 19th, 2005 at 12:35 pm
This works great, but some of my images are quite small. Is there a way to keep them from scaling to greater than 100% of their actual size?
December 20th, 2005 at 4:07 pm
Well, its possible. In Firefox you can use the max-width/max-height styles to limit the size of an individual image. Unfortunately, IE ignores this super-useful style.
I haven’t tried this, but if you want to support IE and you don’t mind something a little less elegant, you can pursue this approach. Remove the width=”100%” from the images and scale the images themselves. While scaling the images either give them the scaled width or their max width, whichever if smaller. This implies that you will need to store their max width somewhere (in the ID as a previous poster suggested, in the image name, in a JS arrary, etc). You will likely still need to scale the DIVs themselves to keep the images nicely arranged in a grid.
Happy coding!
December 26th, 2005 at 5:39 pm
Alright everyone,
I’m making a picture viewer for my personal website at the university.
I’ve no real knowledge of javacript other than what people have prepackaged. (I can change the target and links but creating the script… not gonna happen.)
ANyway, I’m wondering if there is a way that a picture can be put into a table so that it will be as big as possible without being bigger than the window. (Like the auto resize option in IE when only veiwing an image… and one can expand it if one wants.
Is it possible to make the value of the window size to be the value of the picture slider?
December 31st, 2005 at 5:39 pm
Could you possibly link a zip file with all the required pages and a simple example of the post? The same prototype file and the same scriptaculous file that you used? I have tried following your instructions as well as making copies of some of the other posted test pages but cannot get this example to work. All I get when I click on the slider is a circle with a line through it. I have all of the appropriate files linked and in the correct directory but cannot figure out why the slider is not activated. I would appreciate any help that you could provide. Also, thanks much for the great article.
January 1st, 2006 at 9:54 am
I’ve got it working, but I’ve got a problem, in FireFox (or any other Gecko based browser) the pictures do not align correct when using pictures with different heights, see screendump:
http://www.shrani.si/pics/photo-re214009.jpg
Is there an ‘easy’ solution?
Thanks,
Kasper
January 2nd, 2006 at 7:46 am
Here’s another working example, this time using images of mixed width and height (some landscape some portrait).
There are a few bugs like the fact that until the images have all loaded the layout is distorted but other than that it seems to be working fine.
http://www.photostream.info/image-scaler/
January 3rd, 2006 at 4:56 pm
After a lot of tweaking, I’ve partially integrated the image scaler into my personal website and added a cookie function to save the previously set image size:
http://www.interplod.com/
February 1st, 2006 at 7:01 pm
Here is my code and I would really appreciate if someone can enlighten me why my slider is not working?
It does load all the pic however I can’t move the slider towards my right. Its just static does not move at all. I am new to this and yours HELP would be great.
Also I am going to load lots of pictures. Is there any way I can seperate pictures according to specific evenets? Such as NewYears Eve (this will have all the pictures from New years Eve 2006). Then Baseball events for Spring 2006 etc.
Please need yours help.
Thanks
________________________________________________________________________
Vertical Images Demo
Vertical Images: Demo
_______________________________________________________________________________
Do I need to create this slider_test.css file? If so what would be the content of this file.
Thank you
February 6th, 2006 at 3:42 pm
This is awesome. Thank you so much. I’ve got just the palce for this in my bag-of-tricks.
=C=
February 6th, 2006 at 4:31 pm
I thought the same thing after seeing the fluxiom movie, i figured it all out in my head though.
February 7th, 2006 at 12:30 pm
This is excellent. I may add this to one of my blogs just to say that I did it =).
February 17th, 2006 at 2:53 am
Thanks John for a wonderful tutorial.
Can’t wait to try it out.
Frank
April 16th, 2006 at 12:54 am
very interesting stuff…thanks for the resource
April 18th, 2006 at 1:05 pm
I’m having a problem
THe images are added to the page dynamically using ajax. Everything works fine in firefox but in ie6 only the very first image is resized
Any ideas, Thanks
My code:
function resize(v){
floorSize = .3;
ceilingSize = 1.0;
v = floorSize + (v * (ceilingSize - floorSize));
for (i=0; i
April 18th, 2006 at 1:07 pm
Rest of code:
for (i=0; i = scalePhotos.length; i++) {
var prev = container[i].style.height;
scalePhotos[i].style.height = (v*190)+’px’;
var scale = container[i].style.height/prev;
container[i].style.width = container[i].style.width/scale+’px’;
}
}
//The below code is only run after the page has been updated//
var demoSlider = new Control.Slider(’handle1′,’track1′,
{axis:’horizontal’, minimum: 0, maximum:200, alignX: -5, increment: 1, sliderValue: 1});
container = document.getElementsByClassName(’photocontainer’);
scalePhotos = document.getElementsByClassName(’photo’);
demoSlider.options.onSlide = function(value){
resize(value);
}
demoSlider.options.onChange = function(value){
resize(value);
}
May 8th, 2006 at 3:53 pm
Great stuff.
I did a version of my own, which can be seen on my site (link below).
It can deal with images of different sizes (thanks to Jamie Longstaff’s demo for giving me the idea on how to do that) and works in the three major browsers.
I wrote the slider script myself (for the sense of satisfaction :P).
Thanks for the inspiration.
http://www.theejit.com/slider/
June 14th, 2006 at 2:49 am
Amazing stuff Really good one
July 11th, 2006 at 2:13 pm
I know you didn’t invent this control style exactly but you inspired my Flash version here:
http://pixelfumes.blogspot.com/2006/04/tray-style-resizer.html. Thought I’d share.
-Sarge
July 25th, 2006 at 11:51 pm
I wanted to do an image resizing site, and I started thinking about how to do it. Then, I remembered this technique.
Your ideas helped me make my idea better.
thank you.
August 1st, 2006 at 6:44 pm
Nice example! I like it a lot but why not just resize the images instead of having them resized by divs?
Nonetheless good work…
Anyone know how to do something to select divs like this?
http://blog.fluxiom.com/2006/3/29/assets-selected
August 8th, 2006 at 3:17 am
This powerful and flexible, yet easy to use utility will help you to resize thousands of your pictures. Media Resizer quickly and easily prepares your image collections to be published on the web.
http://www.purchaseshareware.com/multimedia-design-media-management/media-resizer5201-1.htm
August 12th, 2006 at 12:18 am
I wanted to do an image resizing site, and I started thinking about how to do it. Then, I remembered this technique.
Your ideas helped me make my idea better.
thank you.
September 13th, 2006 at 6:43 pm
Thank you very much for this script resource.
Is it possible to place a link to this resource at
http://www.featurepics.com/news/PhotographyTips.aspx?
(Photography tips)
October 1st, 2006 at 9:27 pm
nice resource…thanks!
October 9th, 2006 at 5:11 am
Very nice and amazing effort. Keep it up.
November 15th, 2006 at 10:32 am
Nice example! I like it a lot.
http://www.epeaksoft.com/service/odc.htm
November 24th, 2006 at 6:46 pm
for some reason i got the error msg:
this.track has no properties
in the slider.js on row 175
anyone know why?
November 26th, 2006 at 11:50 pm
Great tutorial, worked well for me on my new site.
December 18th, 2006 at 8:46 am
well i have implemented that on my site, offering free image hosting… altered bit of the code to fix the portrait and landscape images to fix in a specific space…
very beautiful code
http://www.aalaphotos.com
February 1st, 2007 at 4:13 pm
Excelent
March 12th, 2007 at 5:23 am
hello nice work keeptup
March 12th, 2007 at 3:29 pm
great site and interesting too.
April 9th, 2007 at 7:12 pm
Very nice! Thanks a lot
April 19th, 2007 at 2:47 am
Works great on Firefox 2 , but slow on IE7…
Good Stuff !! Thanks for sharing.
May 9th, 2007 at 5:59 am
hey
cool tut
does this work for videos as well??
thx
May 31st, 2007 at 5:24 am
looks great and working allmost perfectly becose it has some bugs , on Opera 9.20 the slider is working in mirror mode and on IE7 Mozzila and Opera the small image inside the slider it cannot go to full right
maybe you can help with this issue?!
thanks