Smooth scrolling image list

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="imageBox">
  <div id="imageBoxInside">
    <img src="http://blogs.missiondata.com/wp-admin/images/turtle_sm_1.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/elephants_sm_1.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/turtle_sm_2.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/elephants_sm_2.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/turtle_sm_3.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/elephants_sm_3.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/images/turtle_sm_4.jpg" />
    <img src="http://blogs.missiondata.com/wp-admin/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.

<style type="text/css">
#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.

<script>
function moveToPrevious()
{
  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 });
}
</script>

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="moveToPrevious(); return true;"><img src="http://blogs.missiondata.com/wp-admin/images/previous.png" />
< a href="javascript:void(0);" href="javascript:void(0);" onclick="moveToNext(); return true;"><img src="http://blogs.missiondata.com/wp-admin/images/next.png" />

And that is all there is to it. See it in action!

del.icio.us:Smooth scrolling image list digg:Smooth scrolling image list spurl:Smooth scrolling image list wists:Smooth scrolling image list simpy:Smooth scrolling image list newsvine:Smooth scrolling image list blinklist:Smooth scrolling image list furl:Smooth scrolling image list reddit:Smooth scrolling image list fark:Smooth scrolling image list blogmarks:Smooth scrolling image list Y!:Smooth scrolling image list smarking:Smooth scrolling image list magnolia:Smooth scrolling image list segnalo:Smooth scrolling image list gifttagging:Smooth scrolling image list

18 Responses to “Smooth scrolling image list”

  1. Bernardo Raposo Says:

    Hi, is there any way to stop the scrolling at the last image as Flickr does?

    Thanks in advance.
    BR

  2. carsonm Says:

    Bernardo,

    The simple answer is yes. The way you make it stop depends on if you know in advance how many images you have before you display the page. If you know in advance you can just put a simple if statement in the next/previous code to stop it. As soon as I have time I’m planning on making a little more in depth example that uses this scrolling code again along with the flikr api.

  3. Bernardo Raposo Says:

    Thanks for your reply, actually it was quite simple to implement your aproach, I wonder why I haven’t seen it before :)

    My problem is solved, but I’m looking forward to see your example.
    Cheers.

  4. trecko Says:

    so, back to Bernardo’s question:
    I’m not very saavy with javascript; say I have 13 images to scroll through, how exactly would I construct the if statement to keep the images from scrolling into oblivion?

    Thanks for any help!
    -trecko

  5. carsonm Says:

    I’ve written a second example to show how to stop the scrolling after a number of images: example2

    You need to know how large your view window is, in this case 2 images, and how many total images you have. The main modification is to the previous and next functions as well as a few new variables.

    
    var currentImage = 0;
    var totalImages = 8;
    var viewSize = 2;
    
    function moveToPrevious()
    {
      if(currentImage > 0)
      {
        new Effect.Move('imageBoxInside', { x: 180, y: 0, transition: Effect.Transitions.sinoidal });
        currentImage--;
      }
    }
    
    function moveToNext()
    {
      if(currentImage < totalImages-viewSize)
      {
        new Effect.Move('imageBoxInside', { x: -180, y: 0, transition: Effect.Transitions.sinoidal });
        currentImage++;
      }
    }
    
    
  6. Tom Says:

    Ok I’ve been playing with this, and it looks pretty darn good.
    One enquiry, is it possible to make a ’smooth’ scrolling action such that when you hover your mouse over the left/right keys, the div scrolls in the appropriate direction, stopping only on the onmouseout event?

    This would be very useful for me, and I can’t currently figure out how to do this smoothly!

  7. Lukster Says:

    Hey,
    I was wondering, and this may seem ridiculous but I really don’t know much about Javascript, if it’s not too much trouble, could you should me a way to make it so that the images don’t slide in? I really just want to be able to press the button and have the next picture in a sequence appear. Thanks a lot!

    Lukster

  8. Lukster Says:

    Oh I figured it out :S, sorry!

  9. darrend Says:

    Hey Lukster,

    How’d you do it?

  10. Lukster Says:

    Well, in the code above there’s a line that says:

    {
    new Effect.Move(’imageBoxInside’, { x: 180, y: 0, transition: Effect.Transitions.sinoidal });
    }

    Well, the transition effect there is called ’sinoidal’, and if you change it to ‘full’ then it just jumps directly however many pixels you specify. So in this case it would go 180px to the right. So the new code would be:

    {
    new Effect.Move(’imageBoxInside’, { x: 180, y: 0, transition: Effect.Transitions.full});
    }

    Let me know if it works for you, I really don’t know much about the code though.

    If anyone knows a way to have the images start in the middle of a list of pictures that would be awesome. I have a list of numbers from 1-60 and I when you click on an arrow, it jumps up to the next number. Right now it starts at 1, and goes to 60 so thats fine, but I want it to start at 30.. any suggestions?

    Here’s what I have so far:
    http://www.lbaths.nwdband.com/control.php

  11. CassidyHunt Says:

    I was wondering why this does not work when you declare a doctype of:

    For some reason it loads correctly but when you scroll it pops out of the div and does not observe the overflow: hidden.

    THanks

    Cassidy

  12. did Says:

    First of all, thank you for the concept, it saved me a lot of time !

    here, a little improvment in order to fix problems, for instance, when an user clicks many times and quickly on one of the buttons. I hope that it will help someone !

    function moveToPrevious() {
    if (currentImage > 0) {
    new Effect.Move(’imageBoxInside’, { x: 180, y: 0, afterFinish: function(e) { currentImage–; }, transition: Effect.Transitions.sinoidal, queue: { position: ‘end’, scope: ‘global’, limit: 1 }});
    }
    }

    function moveToNext() {
    if (currentImage

  13. naudjf Says:

    hi,

    I want to use this, but I want my images to be clickable. -> I put my images between and tags. Problem is : it works fine with opera , firefox and Internet explorer but not with Safari…(which is N°1 browser on MACOS). The behaviour is very strange : images don’t move bu their links seems to do. The other strabeg thing is that links are still clickble on areas where the image they are attahced to, are not….so bizzare ! Well, if someone have an idea, I sure would like to read it ! Bye

  14. Antonio Says:

    This does not work in Opera 9.01 in Linux.
    The images in the imageBoxInside div are not aligned in a single smooth scrolling row, but instead are aligned on more rows.
    It looks like Opera is ignoring the width setting for the div imageBoxInside or the overflow setting for the div imageBox.

    Does anyone know a workaround for this?

    Thanks,
    Antonio

  15. hjb Says:

    A little improvement to stop a user clicking while the images are moving:

    var currentImage = 0;
    var totalImages = 8;
    var viewSize = 2;
    var wait = 0;

    function moveToPrevious()
    {
    if(currentImage > 0 && wait == 0)
    {
    wait = 1;
    new Effect.Move(’imageBoxInside’, { x: 180, y: 0, transition: Effect.Transitions.sinoidal });
    currentImage–;
    wait = 0;
    }
    }

    function moveToNext()
    {
    if(currentImage

  16. Mike Says:

    Regarding the no DocType issue in IE.

    I’ve added position:relative; z-index:3 to the #imageBox selector and that seemed to have fixed it.

    Peace

  17. James Says:

    Carson,

    Thanks for the script! Is there any fix for Safari 1/2 yet? Safari beta 3, seems to work fine, but not on 1 or 2. Email me if you’ve figured out a solution or cause of the problem.

    Thanks. James.

  18. Carl Says:

    Hi,

    Just wanted to post a safari fix:

    #imageBoxInside { width: 10000px; left: 0; top: 0; }

    Cheers,
    Carl.

Leave a Reply