Making a Great jQuery Image Slider

February 13, 2012 at 6:10 pm By
Download Demo

Inspired by the Mac App Store

I was on the Mac App Store yesterday and I couldn’t help but notice their very pretty image slider. It automatically slides down every so often, but once you interact, you can ‘push’ an image onto a larger canvas to display it. Sort of like this:

The previous image will then fade out and appear at the top of the image list at the side.

What we Want

I find it’s good to name a list of features we want what we’re making to have. That way you can stay focused!

  • 4 Images Rotation (You can add more by messing around with the code)
  • The rotator should automatically rotate without user intervention
  • Fade in images on the main area
  • On leaving the tab the rotator should stop (this’ll stop any problems we might otherwise have)
  • Two images for each link: A big image and a small one for the side bar.

Begin!

So first off we create your average HTML page, and sort out some alignment and structure. The Structure of the image slider looks like this:

</pre>
<div id="image-rotate">
<div id="main-image"></div>
<div id="side-images">
<div id="up-arrow"><img src="up.png" alt="" /></div>
<div id="image-1"><a href="#"><img src="1.jpg" alt="" /><img src="1s.jpg" alt="" /></a></div>
<div id="image-2"><a href="#"><img src="2.jpg" alt="" /><img src="2s.jpg" alt="" /></a></div>
<div id="image-3"><a href="#"><img src="3.jpg" alt="" /><img src="3s.jpg" alt="" /></a></div>
<div id="image-4"><a href="#"><img src="4.jpg" alt="" /><img src="4s.jpg" alt="" /></a></div>
<div id="down-arrow"><img src="down.png" alt="" /></div>
</div>
</div>
<pre>

We have the main <div> for holding the main image, and then the side-images div for holding all the other stuff. Inside that we have an up and down arrow, and 4 image divs. In each image div Is the large image (outside the span) and the smaller image (inside the span). This is all linked to something with an anchor, so we don’t have to have two anchors.

CSS

The CSS is simple too!

#image-rotate {
	width: 900px;
	height: 300px;
	overflow: hidden;
	margin: 0px auto;
	box-shadow: 0px 2px 4px rgba(0,0,0,0.3);
	position: relative;
	top: 100px;
}
#main-image {
	width: 650px;
	float: left;
	position: relative;
	height: 300px;
	background: #343434;
}
#side-images {
	float: left;
	height: 300px;
	position: relative;
}

#side-images div[id^=image] {
	height: 100px;
	width: 250px;
	overflow: hidden;
	position: relative;
	padding: 0;
	z-index: 3000;
}

#main-image div { display: none; position: absolute; }
#main-image img { display: block; }
#main-image span img { display: none; }

#up-arrow, #down-arrow {
	background: #343434;
	cursor: pointer;
	border-radius: 20px;
	width: 26px;
	height: 21px;
	box-shadow: 0px 0px 20px rgba(255,255,255,1);
	opacity: 0.8;
	z-index: 5000;
	text-align: center;
	color: #fff;
	left: 111px;
	margin: 10px 0;
	position: absolute;
}

#up-arrow { top: 0; padding: 4px 0 0 0; }
#down-arrow { bottom: 0; padding: 6px 0 0 0; }
#side-images img { display: none; }
#side-images span img { display: block; }
#up-arrow img, #down-arrow img { display: inline; }

#up-arrow:active, #down-arrow:active {
 	box-shadow: 0px 0px 5px rgba(255,255,255,1), inset 0px 0px 15px rgba(0,0,0,1);
}

Basically we set the width of the main image (600×300) and the width of the smaller images (100×250) and make sure there is no overflow (overflow:hidden). Then we float a few things so that the side-images will appear beside the main-image. Pretty straight forward, right? Lets take a look at the jQuery.

jQuery

The jQuery is surprisingly simple, so hopefully you’ll be able to pick up a few of the basics in this tutorial. Don’t forget to include the jQuery in your html before this file. First off, we initiate jQuery, and set a bunch of variables we’ll use later.


$(document).ready(function() {

	var number = 0;
	var interval = 0;
	var timer;

Next set a timer, so that the script will automatically click the down arrow every so often (every 3000ms). We use the Javascript function setInterval and run ‘click’ in jQuery for the down arrow. We defined the timer variable earlier because we’re going to change it every now and then.

	timer = setInterval(function() {

		$('#down-arrow').click();

	}, 3000);

So we want the image rotator to only change automatically when the user is on that page. So we need to disable the interval we set earlier on blur (The javascript function for when the user leaves an object). Then on return (focus) we’ll reinitiate the timer. I implemented this because of some issues I had were the images would stack above each other. This fixes it.

	/* Window blur and focus functions, to set timers when the user changes the tab or returns */
	$(window).blur(function() {

		clearInterval(timer);

	});

	$(window).focus(function() {

		timer = setInterval(function() {

			$('#down-arrow').click();

		}, 3000);

	});

At this point I knew I was forgetting something! I almost forgot to set the default image. I just made it the first image you added. So all that’s happening is you’re moving (appending) the first image div to the #main-image, and it fades in.

	/* Default Image */

	$('#side-images [id^=image]:first').appendTo('#main-image').fadeIn();

Now lets make the arrows actually work! No point setting those timers if the down and up arrows dont function. There are some slight differences between each. Lets take a look at the down arrow first. To start we need to initiate the click, and check if the animation is running. If animationWait is still zero then it isn’t. Then we set animationWait to 1 (Now the animation is running).

$('#down-arrow').click(function() {

	if(animationWait == 0) {
		animationWait = 1;

Next we want to append the main image to the side images. We clone it so we can keep the event handlers (which would disappear if we just appended it). So momentarily we’re going to have two versions of the same thing, but we’ll remove one in a little while. I’ve also changed display to block, because the CSS has it hidden, and reset the style attribute.

	$('#main-image [id^=image]').attr('style', '');
	$('#main-image [id^=image]').addClass('fading').css({'display':'block'}).clone().appendTo('#side-images');

Now we initiate the main animation to slide down the images, to create a continuous effect. I’ve made a function which checks if the number variable we set earlier is still zero, and add to it if it is. That way we dont append all the side images to the main image! Oh and I removed the style attribute, so it was a clean slate for the newly appended image.

	$('#side-images [id^=image]').animate({top: '0'}, 250, function() {

		$('#side-images [id^=image]').attr('style', '');
		/* Only run animation once */
		if(number == 0) {

			$('#side-images [id^=image]:last').appendTo('#main-image').fadeIn();
			++number;
		}

	});

Remember earlier we cloned the main image? We have to remove it! That way it looks like its fading from image to image. It’s not really, it’s a trick! Then we reset the number variable to 0 so that we can run the animation again. Otherwise the arrows would only work once. That’s the up arrow completed.

	/* Set timeout so animation is done */
	setTimeout( function() {

		animationWait = 0
		$('#main-image .fading').remove();
		$('#side-images .fading').removeClass('fading');
	}, 300);

	number = 0;

});

Now before we get onto the down arrow, we need to check if the user is hovering over the image rotator or not. If they are hovering over it, they’re interacting with it. So we should stop the timer. If they hover back off the image rotator, we should reinitiate the timer.

/* When hovering clear the interval, because
the user is interacting */
$('#image-rotate').hover(function() {

	clearInterval(timer);

}, function() {

	timer = setInterval(function() {

		$('#down-arrow').click();

	}, 3000);

});

The down arrow is very similar to the up arrow. This time I prepended (before) rather than appended, and moved the image up 100px so that we could get a nice slide down effect.


$('#down-arrow').click(function() {

	/* Check if animating */
	if(animationWait == 0) {
		animationWait = 1;
		$('#main-image [id^=image]').css({'display' : 'block'}).addClass('fading').clone().prependTo('#side-images');
		$('#side-images [id^=image]').css({'top': '-100px'});

		$('#side-images [id^=image]').animate({top: '0'}, 250, function() {

			$('#side-images [id^=image]').attr('style', '');
			/* Only run animation once */
			if(number == 0) {

				$('#side-images [id^=image]:last').appendTo('#main-image').fadeIn();
				++number;
			}

		});

		/* Change animation after a certain amount of
		time */
		setTimeout( function() {

			animationWait = 0
			$('#main-image .fading').remove();
			$('#side-images .fading').removeClass('fading');

		}, 300);
		number = 0;
	}

});

});

Now all you have to do is include the Javascript in the head of your HTML and you’re done!

&lt;script type=&quot;text/javascript&quot; src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;scroll.js&quot;&gt;&lt;/script&gt;

Check out the demo below to see it for yourself! I’ve also included a download link, so you can use this on your site. You can use this for any project you want, and you don’t have to link back or give credit! I hope you’ve enjoyed this tutorial, don’t forget to share this article, it really helps.