I'm using the following JS code to build a horizontal image carousel that scrolls on hover. The mousemove
event detects the position of the mouse over the container and scrolls to the left or to the right accordingly. Everything works as I expect but if I move the mouse over the container while the animation is running, it becomes a bit jerky.
Is there any solution for this?
Thanks
JS:
$( '.carousel-frame ul' ).mousemove( function(e) {
var container = $(this).parent();
if ((e.pageX - container.offset().left) < container.width() / 2) {
var direction = function() {
container.animate({scrollLeft: '-=600'}, 1000, 'linear', direction);
}
container.stop().animate({scrollLeft: '-=600'}, 1000, 'linear', direction);
} else {
var direction = function() {
container.animate({scrollLeft: '+=600'}, 1000, 'linear', direction);
}
container.stop().animate({scrollLeft: '+=600'}, 1000, 'linear', direction);
}
}).mouseleave( function() {
var container = $(this).parent();
container.stop();
});
CSS:
.carousel-frame {
width: 100%;
margin-bottom: 0.5em;
padding-bottom: 1em;
position: relative;
overflow-x: scroll;
white-space: nowrap;
}
.carousel-frame ul {
margin: 0;
padding: 0;
height: 100%;
list-style: none;
}
.carousel-frame li.carousel-item {
cursor: pointer;
display: inline-block;
margin: 0 5px 0 0;
padding: 0;
}
HTML:
<div class="carousel-frame">
<ul>
<li class="carousel-item">
<img src="http://placehold.it/200x150" />
</li>
<li class="carousel-item">
<img src="http://placehold.it/200x150" />
</li>
<li class="carousel-item">
<img src="http://placehold.it/200x150" />
</li>
<li class="carousel-item">
<img src="http://placehold.it/200x150" />
</li>
<li class="carousel-item">
<img src="http://placehold.it/200x150" />
</li>
</ul>
</div>
FIDDLE:
There are two major changes required to get a smooth effect:
One: When trying to create smooth animations always go for
window.requestAnimationFrame
...Two: In your example you are detecting mouse events on the
ul
, which means that the animation is interrupted every time the cursor passes a "gap" between theli
elements.Updated fiddle: https://jsfiddle.net/dk6f3snf/6/
Note that I also made the speed depend on how far the cursor is from the middle, rather than only which half it is over and slowed it way down... mostly to demonstrate how smooth using the
window.requestAnimationFrame
method makes things.Update
Actually to make the speed consistent on different devices and regardless of other stuff "stealing" resources, I guess you need to consider the time elapsed between frames as well. I've updated the fiddle demonstrating this: https://jsfiddle.net/dk6f3snf/7/
Update
I think your question about multiple carousels on a single page is an entirely different subject than your original question... but one way would be to just wrap it in a simple plugin - example: https://jsfiddle.net/dk6f3snf/8/