Thu 16 Feb 2006
I had someone ask me about fitting more images in a small area and the way flickr does their image scrolling came to mind. I wanted to see how hard it was to do and as it turns out it isn't hard to do at all thanks to script.aculo.us.
I'm making this as simple as I can to illustrate just how nice the new tools like script.aculo.us are.
Step 1. You need a box and some images. You will also need to know the size of the images or at least the size of the largest one. In an attempt to keep this simple I'm going to assume all the images are the same size.
<div id="imageBoxInside">
<img src="http://www.ioncannon.net/examples/slide/images/turtle_sm_1.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/elephants_sm_1.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/turtle_sm_2.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/elephants_sm_2.jpg" />
<img src="http://www.ioncannon.net/examples/slide/mages/turtle_sm_3.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/elephants_sm_3.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/turtle_sm_4.jpg" />
<img src="http://www.ioncannon.net/examples/slide/images/elephants_sm_4.jpg" />
<br/>
</div>
</div>
Notice from this code that we have an outer box and an inner box. We will next want to make the outer box smaller than the inner box so that only a few of the images can be seen at one time.
Step 2. To hide the extra images we give the outer box a set width, in this case I want to show only 2 images at a time and each image is 180px wide so I make the outer box 360px wide. Notice that the overflow is hidden. The hidden overflow is what keeps the images that are in the inner box but not within the outer box's width hidden.
I'm using floats to lay the images out one next to the other. Because of this we need to give the inside box a large width so that it will not wrap the floated images.
#imageBox { margin: auto; width: 360px; border: 1px #000 solid; overflow: hidden; }
#imageBoxInside { width: 10000px; } #imageBox img { float: left; padding: 0px; margin: 0px; }
#imageBox br { clear: both; }
</style>
Step 3. Now for the magic. You need the latest version of script.aculo.us because I use the Effects.Move function and they have changed Effects.MoveBy to Effects.Move only recently.
We now create two functions to move the images ether one step to the right or one step to the left. Each step is the size of a single image so the when one is hit it moves one image out of thew view and another image into view. As you can see from the following code this is extremely easy using the script.aculo.us library.
{
new Effect.Move('imageBoxInside', { x: 180, y: 0, transition: Effect.Transitions.sinoidal });
}
function moveToNext()
{
new Effect.Move('imageBoxInside', { x: -180, y: 0, transition: Effect.Transitions.sinoidal });
}
Step 4. The only thing that remains is to connect everything together. We add a couple links to move call the next and previous functions defined above.
<a href="javascript:void(0);" href="javascript:void(0);" onclick="moveToNext(); return true;"><img src="http://www.ioncannon.net/examples/slide/images/next.png" /></a>
And that is all there is to it. See it in action!
Tags: javascript, script.aculo.us


















July 8th, 2006 at 6:45 am
[...] This is a great article about the yahoo ui tools. I mention it mainly because they have a nice scrolling widget a lot like what I put together as an example of the things you can do with script.aculo.us (see Smooth Scrolling Image List). [...]
November 24th, 2006 at 9:18 am
Very great article! Thx
Could you tell me how can i add a link on every image? The basix idea is to scroll an image list but maybe it could be great to add the ability to click on each image to visit a website.
November 27th, 2006 at 9:29 am
Etan, you can just put a link around each img and that should do what you want.
January 29th, 2007 at 11:57 am
wonderful! just what i was out for. but what if I wanted to stop the scroll once the pics are over? now it just scrolls to infinity!? even if i reduce the "width".. am i missing something?
thanks
April 3rd, 2007 at 4:45 am
zeeker: I used the "left" value of the ImageBoxInside to determine the scroll buttons:
if left is 0, ImageBoxInside is on the very left, so hide left scroll arrow
if left + width of the ImageBoxInside = width of imageBox, ImageBoxInside is on the very right, so hide right scroll arrow.
if width of ImageBoxInside
April 30th, 2007 at 11:00 am
Hi,
I am new to script.aculo.us so I would like to know how the above script works if I use it in my webpages??Is there any configuration/installion for any script.aculo.us ??or we can copy the reqd functions from the library?I am confused here..Please help me out.
April 30th, 2007 at 11:25 am
Please ignore my previous comment! i got it worked but I would like to know whether is there any way to display end of gallery if we reach the last image because right now if we keep pressing the right arrow after the last image its just show the white space and we have to refresh the page or click the left arrow for equal number of times we clicked the right arrow..
Please help me out.
Thanks
Pragan
February 4th, 2008 at 6:31 am
Hi, it's the first time I use scriptaculous, but this article is easy to do. However, there is a problem, when I use DTD XHTML 1.0 Trasitional (-!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"-
-html xmlns="http://www.w3.org/1999/xhtml"-…), the page is ok in FF, but it is not correct in IE6. When I click on the arrow button the "imageBoxInside" expands horizontally over the "imagebox" (not inside it like FF).
I tried to cancel the DTD on my page and everything is ok in both FF and IE6. But it affects another problem of the page.
Please help me solve this problem.
Thank you so much.
luutieuduong
February 16th, 2008 at 7:12 pm
Great article and really nice implementation. The only problem that happens is when you click the scroll arrows quickly several times, the images display out of line. Is there a way to prevent the script from firing until the scroll is complete??
March 18th, 2008 at 12:36 pm
I have the exact same problem as "luutieuduong". Anyone who has a solution?
The problem is that the Effect.Move changes the style property for imageBoxInside from position: static to position: relative. So in IE6+IE7 this causes the same problem for me as for "luutieuduong". See www(dot)andersroth(dot)se.
March 18th, 2008 at 12:43 pm
Adding "position: relative" to the imageBox-css fixed the problem for me, both in IE6 and IE7.
I hope this fix will work for anyone else with the same problem!
April 2nd, 2008 at 3:35 pm
nice article.
but same problem. the next button moves the div to infinity. any solution?
regards.
April 8th, 2008 at 2:23 pm
@EC :
I had the same problem in a site I was working on. Adding the declaration
queue: 'end'
to the effect properties solves that problem. The move will still be recorded, but it won't start until all currently running moves have finished.
April 26th, 2008 at 2:19 pm
Thanks Christofer. Your solution solved the IE6 position problem. Very helpful. Thanks.
May 30th, 2008 at 5:24 pm
how to make it go back when it reaches the end?
June 3rd, 2008 at 4:35 am
That does not circulate at the end.
June 6th, 2008 at 5:22 pm
could someone better explain how correct the scrolling to infinity issue? If goldenapples queue:'end' works, how exactly does it get added to the code?
Thank you!!!
September 18th, 2008 at 5:51 am
In case it may help I have implemented a solution to avoid to scroll beyond the limits of the list (it uses prototype functions) :
Update the js:
function moveToPrevious(boxDivId, contentDivId, imageWidth)
{
var contentPosition = $(contentDivId).cumulativeOffset();
var boxPosition = $(boxDivId).cumulativeOffset();
if (contentPosition[0] (boxPosition[0] + boxWidth)) {
new Effect.Move(contentDivId, { x: -imageWidth, y: 0, transition: Effect.Transitions.sinoidal });
}
}
Replace css by:
#imageBox { margin: auto; overflow: hidden; position: relative;}
Here is an example of the html:
prev
next
Note that in this example, images are 400 px wide.