UPDATE: Component has been updated. Get it here.

I recently came in need of a horizontal scrolling image gallery written i JavaScript. The idea was to autoscroll on mouseover. Clicking the thumbnail would open the image in a nice Lightbox. See the example here.

I have worked with JavaScript frameworks like Dojo, Mootools and Prototype, but for this project I decided to give jQuery a go.

While googling the subject all the other examples I came across didn’t quite accomplish what I had in mind; I wanted the auto-scroll to accelerate the closer the mouse would come to the edge of the gallery. The other examples were using the mouse pointer x-coordinate to determine the gallery’s amount of x-scroll, making a direct relationship between those two parameters. This is fine for galleries with maybe 10 thumbnails, but for larger galleries the scrolling speed and accuracy will become an issue.

For the lightbox effect I used the jQuery Lightbox plugin. If one wishes to use this as a video gallery, check out the jQuery Videobox plugin.

Let’s look at the code.

HTML

The HTML is pretty forward (complete code example available for download at the end of the article):

<div class="galleryWrapper">
  <ul class="galleryItems">
    <li>
      <a href="photos/big/image1.jpg" title="A title here">
        <img src="photos/image1.jpg"/>
      </a>
    </li>
    <!-- Repeat as many items here as needed -->
  </ul>
</div>
<script type="text/javascript">
  $('.galleryItems a').lightBox({fixedNavigation:true});
</script>

There’s a div wrapper which can have a width, border, background-color and so on. Then there’s the ul, which will be the moving element. It’s width will be calculated dynamically later on. Inside the ul you have the li elements containing thumbnail images which can be clicked to activate the lightbox. Add as many li elements as needed.

The lightbox javascript a the bottom will turn all a elements in galleryItems into lightbox style pop-ups. The fixedNavigation parameter can be omitted, it is a matter of taste.

CSS

The CSS is also straight-forward.

.galleryWrapper {
  width               : 920px;
  overflow            : hidden;
  border              : 1px solid #ccc;
  margin              : 0 auto;
}

.galleryItems {
  display             : block;
  margin              : 0;
  list-style          : none;
  padding-left        : 0;
}

.galleryItems li {
  display             : inline;
  float               : left;
  padding             : 0 4px;
}

.galleryItems li img {
  border              : 1px solid #777;
}

.galleryItems a {
  display             : block;
  text-decoration     : none;
}

.galleryItems a:hover img {
  filter              : alpha(opacity=70);
  opacity             : 0.7;
}

The galleryWrapper div should have a fixed width and overflow set to hidden. Border and margin are optional.

The CSS for the galleryItems ul basically makes the unordered list behave like a horizontal gallery.

The li elements are displayed in line, floated with a little padding in between.

Only thing left to notice is that the images will display semi-transparent on mouseover (hover).

JavaScript / jQuery

The JavaScript and jQuery is a little more complicated and I will not explain everything in detail.

// Constants
var boxWidth = 250; /* width of the mouseover boxes left and right */
var brake = 80; /* the bigger this number, the slower the movement */
var t;

window.onload=function () {
  var div = $('.galleryWrapper');
  var wrapperWidth = div.width();

  var numberOfItems = $(".galleryItems").children().length;
  var itemWidth = $(".galleryItems").children(":first-child").outerWidth();
  var maxScrollLeft = (itemWidth*numberOfItems)-wrapperWidth+20;
  $(".galleryItems").css("width", (itemWidth*numberOfItems)+"px")

  div.mouseover(function(e) {
    if((div.scrollLeft()>=0) && (div.scrollLeft()<=maxScrollLeft)) {
      moveIt(e, wrapperWidth);
    }
  });

  div.mousemove(function(e) {
    if((div.scrollLeft()>=0) && (div.scrollLeft()<=maxScrollLeft)) {
      moveIt(e, wrapperWidth);
    }
  });

  div.mouseout(function() {
    clearInterval(t);
  });
}

function moveIt(e, wrapperWidth) {
  clearInterval(t);

  var relPos= e.pageX-$('.galleryWrapper').position().left;

  if (relPos>(wrapperWidth-boxWidth)) {
    var acceleration = (((relPos-(boxWidth+100))/brake)^2);
    t = setInterval(function() {goRight(acceleration)}, 13); 

  } else if(relPos<boxWidth) {
    var acceleration = (((wrapperWidth-relPos-(boxWidth+100))/brake)^2);
    t = setInterval(function() {goLeft(acceleration)}, 13);
  }
}

function goLeft(acceleration) {
  var div = $('.galleryWrapper');
  div.scrollLeft(div.scrollLeft()-acceleration);
}

function goRight(acceleration) {
  var div = $('.galleryWrapper');
  div.scrollLeft(div.scrollLeft()+acceleration);
}

First there are some constants you can tinker with.

Next I used the standard window.onload event, instead of using jQuery’s $(document).ready() event, which did seem to have some issues with not firing at the proper moment.

Then I calculate the desired with of the ul element and assign it.

I then add event hooks for both mouseover and mousemove. This prevents the animation from stopping in the spaces between the thumbnails. I also add an event hook for mouseout or the animation would continue.

To keep the gallery moving WHILE mouseover, I use setInterval with a very short interval, 13 milliseconds. I then use the jQuery scrollLeft and scrollRight functions to do the actual movement.

Conclusion

This script leaves room for improvement, but it works as is and is tested in IE6, IE7, Firefox and Safari. A nice touch could be a Javascript scrollbar at the bottom. Also the ability to show Flash video instead of images would be nice.

Resources

Download the source here.

Posted Monday, November 16th, 2009 at 4:45 pm
Filed Under Category: Ajax, CSS, JavaScript
You can leave a response, or trackback from your own site.

41

Responses to “Horizontal mouseover autoscrolling gallery with Lightbox”

Chris Poppe

Hi Klaus,

first of all, a big THANKS for making your code available to people like me, who don’t really have a clue of what’s going on in programming websites…

Well, I am trying to implement your code in our gallery and I am encountiring one big problem. Whilst the autoscrolling works perfectly on its own, it stops as soon as I stick it into my container box. I use this container in order to center my page. The ccs for it looks like this:

#container {float:none; position: relative; width: 1200px; height: 650px; margin: 0px auto; padding: 0px 0px 0px 0px}

Whilst it’s still possible to scroll the images to the right, coming back to the left does not work. Would you have any ideas or suggestions as to what I could try to make it work?

Thanks for your help…

Best regards,

Chris

admin

Hi Chris,

Glad to hear that you could find some use for my code. I’ve tried to insert the lightbox into a container like yours, but I could not reproduce the problems you were having. Do you have an URL where I can access your code? Also please let me know what browser you are using.

Ev

Hi Klaus,

Thanks for sharing your work here – I’d like to use your gallery, and it’s perfect for what I need … though is is easy enough to make it auto scroll..?
what I mean is, instead of the scroll only activating when the user mouseovers right or left, I want it to just scroll automatically.

thanks in advance for your advice
:)

admin

Hi Ev,

First of all, sorry for the late reply, but I’m so busy these days.
Autoscrolling is certainly a possibility, actually it is easier to do than the mouseover. The question is, what do you want the script to do, when it reaches the end, i.e. there are no more images? Do you want to scroll back, or do you just want to keep moving?

Cristian Rusneac

Hello, Klaus!

I would like to use your code to make a scrollable skyline of the city with information being displayed when the mouse is placed over a particular landmark outline. How can I tweak the code to make it loop continuously?

reneechung

Hi Klaus!

Is it possible to set which slide to start first? Thanks.

admin

Hi Renee, You would simply add the following code at the end of the window.onload function:
div.scrollLeft(position of your slide here);
If you don’t know the position of your slide, you can use Firebug or Chrome’s Developer tools to find it.

Hope this help.

Viktor

Thanks for sharing your work. Is there a way to add two buttons to use for scrolling too?

admin

Try take a look at this example and let me know if you that’s what you mean:
http://www.scrapbook-adhesives.com/mystik-permanent-strips-dispenser

Viktor

Something like that. This is what im after:
http://img197.imageshack.us/i/buttonsix.png/
Two buttons below the slide.

admin

Using the aforementioned example you should be able to modify the css to fit your needs. You can also replace the onmouseover event with onclick although I think there are a lot of other solutions out there providing that functionality. Have you looked in the jQuery plugins?

John

Hi Klaus, thanks for posting your code, good stuff!

Is there a way with relative ease to add semi-transparent arrows (just a png) on hover and only when there are more items to display in the respective direction? So, when a user hovers, if there are more items hidden on the right side, the arrow would display, and vice-versa, but would disappear when they reach the end.

Thanks!

admin

Hi John,

You can see a real-world example showing more or less what you are asking for here:
http://www.scrapbook-adhesives.com/mystik-permanent-strips-dispenser

You should be able to examine the code in there and modify it to meet your demands.

Good luck!

John

Excellent, thanks!

Sharlene

Hi,

I’m using this code for my website as a sort of “scrolling menu”. It works perfectly fine with Google Chrome as the browser, but does not work at all with Mozilla Firefox. Is this abnormal, or is this script’s functionality limited to specific browsers? And if it’s abnormal, what should I double-check to ensure that it works in Firefox as well?

admin

Hi Sharlene, Good to hear that my code is being used “out there”. Sounds strange that you have issues with Firefox as it is the browser I’m using. If you provide a URL I could take a quick look…
- Klaus

Sharlene

Hi,

Thanks for your reply! I provided a link. If you go to “sisters” and then “sisters by semester” the script is being used as the menu on top of the content area. In Firefox though, only the first “button” shows up, and there’s no scrolling functionality…

admin

Sorry, but I can’t see the link. Maybe it got lost somehow?

admin

Got it… I’m not sure, but I can see that you are using an iFrame, so it could be that Firefox handles iFrames differently than Chrome.

Robert

Hi Klaus,

Great job on this gallery. I am new to web design and definitely green when it comes to javascript. When I implemented your code into my page the scrolling would only go in one direction. Any thoughts on what I did wrong?

soni kaur

can i have vertical gallery

Stephen Ox

Hi. Great resource. Thank you. My problem is that as you scroll to right it won’t stop at the last image. This is not a problem for Safari and Chrome but is for Firefox and Opera (not tested IE) The web address I have given is a stripped back version of website in an effort to problem solve. the only difference I can see between mine and you example is there are more images and some are wider due to format. Can you help? cheers S

admin

Hi Steven,

Somehow the UL width gets calculated too long. Try setting it manually.

Stephen Ox

Apologies I’m a photographer not a web developer.. Can you give me a little more instruction?

admin

I understand. It’s been quite awhile since I wrote the code so I couldn’t really remember exactly the details of how it was working. Going over it again I noticed that the code is setup for all images to have the same length. You can change that by changing the lines
var itemWidth = $(“.galleryItems”).children(“:first-child”).outerWidth();
var maxScrollLeft = (itemWidth*numberOfItems)-wrapperWidth+20;
to:
var itemsWidth;
for(var i; i < numberOfItems; i++) {
itemsWidth += $(“.galleryItems li:nth-child(” + i + “)”).outerWidth();
}
var maxScrollLeft = itemsWidth-wrapperWidth+20;

Or something like that. Haven’t really got the time to check the code, so give it a try.

Nice pictures by the way.

Stephen Ox

So Close. Got some Syntax errors!

Dave

Thanks very much for the code, with very little tweaking it did exactly what I wanted it to do. I am now trying to add a new feature. I have some links on a different page of my site, that I want to link to their respective thumbnail in the scrolling gallery.

I am guessing the solution will be similar to to renee’s question about setting which slide starts first, but to be honest I haven’t had much luck with that.

Any help would be appreciated, and thanks again for the code in the first place.

Dave

Sorry about that I tried to show you what the link should look like and ended up creating a dummy link,

the link should look like this

a href=”gallery/albummisc.html#400&”

(obviously with the greater than and less than signs)

Hope this makes sens

admin

Thanks for sharing, David.

Amaya

Hello Klaus,

Your code is awesome! Thanks a bunch!

I’m very new to coding, and am having a bit of a problem. I would love to put multiple galleries on the same page. Everything works great with one gallery, but not multiples. I’ve tried everything I can think of, but can’t get it to work. I would really appreciate your help, if your still answering these. This is what the gallery section of my html currently looks like:

Products by Seller

Neo Toys




Neo Toys





$(‘.galleryItems a’).lightBox({fixedNavigation:true});

Sorry if its a lengthy post, but I don’t have a published webpage that I can link to. Thanks in advance!

Evans

Hello,

Wonderful job on this! With a little tweaking, I’m using this on a site I built and it looks great! I’m trying to add arrows or a scrollbar to making scrolling on mobile devices easier, but I’m having a little trouble.

I’ve taken a look at some sites that have this out there but am having trouble successfully replicating it. Any advice?

Thanks!

admin

Hi Kelley,

Here’s a link to the latest version that’s got a lot of options including arrows and what not. Check the jquery.mouseoverscroll-0.5.js file to see the available parameters. Enjoy.
mouseoverscroll-0.5.zip

Francesco

Hello, I have a problem. If I load a horizontal thumbnail in the gallery (example a thumbnail L=450px H=250px), the last 3 or 4 images are displayed in a row below. How can I fix this?

admin

Are you using the latest version?

Harry

Hello,
great work. I wanted to how can I make it into an autoscroll that reverses once it reaches the end.

admin

Thanks for yout comment. Reverse auto-scrolling is not part of the module, but you could eaasily add it yourself if you know a little jQuery.

Harry

But how can make it an autoscroll that goes to the end and stop.

Harry

nvm I got it thanks though

Leave a Reply