Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Create a Simple Slideshow Using MooTools, Part IV: Thumbnails and Captions

25 Responses »

MooTools Slideshow

My "Create a Simple Slideshow Using MooTools" series has been hugely successful. The first step was laying the groundwork for the slideshow, the second step was adding controls and events to the slideshow, and the third step was recoding the slideshow into a sexy class. This fourth slideshow tutorial will add thumbnail previews and captions to the slideshow.

No Class? WTF!?

I've chosen to revert back to the "inline" code from the second tutorial. Why? I'm going a little bit off of the reservation with this one. I think classes are important to use when you want a more generic slideshow; this one will be a bit more customized. That isn't to say, however, that I wont be creating another class in the future.

The HTML

Christina Ricci 1::This is the caption for photo 1. Christina Ricci 2::This is the caption for photo 2. Christina Ricci 3::This is the caption for photo 3. Christina Ricci 4::This is the caption for photo 4. Christina Ricci 5::This is the caption for photo 5.

Isn't it nice that our base HTML code hasn't changed since the first tutorial? :)

The CSS

#slideshow-container	{ width:512px; height:384px; position:relative; }
#slideshow-container img { width:512px; height:384px; display:block; position:absolute; top:0; left:0; z-index:1; }
#slideshow-container-controls { margin:10px 0 0 0; }
	#slideshow-container-controls img { cursor:pointer; width:100px; height:75px; border:1px solid #ccc; float:left; margin:0 1px 0 0; }
#slideshow-container-caption  { height:70px; position:absolute; bottom:0; left:0; right:0; background:#000; z-index:10; overflow:hidden; }
	* html #slideshow-container-caption { width:100%; }
	#slideshow-container-caption h3 { font-size:24px; font-weight:bold; color:#fff; padding:10px 10px 3px 10px; }
	#slideshow-container-caption p	{ color:#eee; font-size:11px; padding:0 10px 10px 10px; }
.toc-active				{ border-color:#000; }

We've added a bit of CSS for the forthcoming controls/thumbnails and the caption elements. The caption will have a black background with light text. The thumbnails will be very small, floated next to each other, with fixed dimensions.

The MooTools JavaScript

window.addEvent('domready',function() {
	/* settings */
	var showDuration = 5000;
	var container = $('slideshow-container');
	var images = container.getElements('img');
	var currentIndex = 0;
	var interval;
	var toc = [];
	var tocActive = 'toc-active';
	var thumbOpacity = 0.7;
	
	/* new: create caption area */
	var captionDIV = new Element('div',{
		id: 'slideshow-container-caption',
		styles: {
			//display:none,
			opacity: thumbOpacity
		}
	}).inject(container);
	var captionHeight = captionDIV.getSize().y;
	captionDIV.setStyle('height',0);
	
	/* new: starts the show */
	var start = function() { interval = show.periodical(showDuration); };
	var stop = function() { $clear(interval); };
	/* worker */
	var show = function(to) {
		images[currentIndex].fade('out');
		toc[currentIndex].removeClass(tocActive).fade(thumbOpacity);
		images[currentIndex = ($defined(to) ? to : (currentIndex < images.length - 1 ? currentIndex+1 : 0))].fade('in');
		toc[currentIndex].addClass(tocActive).fade(1);
		captionDIV.set('tween',{
			onComplete: function() {
				captionDIV.set('tween',{
					onComplete: $empty
				}).tween('height',captionHeight);
				/* parse caption */
				var title = '';
				var captionText = '';
				if(images[currentIndex].get('alt')) {
					cap = images[currentIndex].get('alt').split('::');
					title = cap[0];
					captionText = cap[1];
					captionDIV.set('html','

' + title + '

' + (captionText ? '

' + captionText + '

' : '')); } } }).tween('height',0); }; /* new: create preview area */ var preview = new Element('div',{ id: 'slideshow-container-controls' }).inject(container,'after'); /* new: control: table of contents */ images.each(function(img,i){ /* add to table of contents */ toc.push(new Element('img',{ src: img.get('src'), title: img.get('alt'), styles: { opacity: thumbOpacity }, events: { click: function(e) { if(e) e.stop(); stop(); show(i); start(); }, mouseenter: function() { this.fade(1); }, mouseleave: function() { if(!this.hasClass(tocActive)) this.fade(thumbOpacity); } } }).inject(preview)); if(i > 0) { img.set('opacity',0); } }); /* control: start/stop on mouseover/mouseout */ container.addEvents({ mouseenter: function() { stop(); }, mouseleave: function() { start(); } }); /* start once the page is finished loading */ window.addEvent('load',function(){ show(0); start(); }); });

The first step is creating the caption container within the main image container. We measure the height of the caption container and hide it right away to prevent it from being seen. The next step is adding a few chained tweens within the show method that parses the image's alt attribute, sets the HTML within the caption container, and slides it up and down. I set the HTML of the caption container instead of using MooTools to create new H3 and P elements because (a) setting the HTML is faster and (b) we have no plan to do anything with each element individually.

A preview container is also created to hold the thumbnails. As we cycle through the large images, we create IMG elements with a fixed size (from the CSS above) that will act as thumbnail navigation for the slideshow. As an image receives focus, it's border and opacity changes to show focus. Awesome!

Do you like this version better than the previous? I certainly do. Look forward to a class version soon. Have any improvement ideas? Share them!

Discussion

  1. February 22, 2010 @ 11:05 am

    I believe that the most correct way to mark up images and captions is to use definition lists. The img element’s alt attribute allows us to provide fallback content; captions, however, are not fallback content.

    I’ve created a JavaScript slider for images captioned in this way. [http://davidchambersdesign.com/examples/prototype-image-slider/]

  2. February 22, 2010 @ 12:41 pm

    It’s a bit buggy…sometimes an image shows for longer than normal, and then the next caption and image appears and disappears immediately only to be replaced by the following caption and image…weird… on firefox 3.6

  3. guido
    February 22, 2010 @ 12:55 pm

    Wow, very nice :DDD

    And how do i do this with div’s?

  4. February 22, 2010 @ 4:09 pm

    That is very good stuff, thanks for sharing

  5. February 22, 2010 @ 4:41 pm

    @Adriaan Nel: Mac or PC? I’m on Mac and it’s silky smooooth.

  6. February 22, 2010 @ 6:57 pm

    haunting picture to say the least! thanks for taking the time putting together the tut.

  7. February 22, 2010 @ 7:30 pm

    AMD Turion 2.3, Chrome 4, Windows 7 Home Premium: the animation is quite jumpy…

  8. February 22, 2010 @ 8:22 pm

    Just tested on all Mac browsers (Firefox, Chrome, Safari, Opera) and looks good. Slight jump in Opera but still looks good. Will investigate Windows-based browsers more.

  9. February 22, 2010 @ 10:37 pm

    Checked on Virtual Box / IE6, IE7, IE8 and it looked all good. I’ll check on native Windows tomorrow.

  10. negative
    February 22, 2010 @ 11:44 pm

    make it more user friendly – animation should stop when mouse pointer is on main image or thumbnails

    anyway, nice tut!

  11. February 23, 2010 @ 12:03 am

    @David Walsh: on Windows 7, but did you adjust the display time of each slide or something, as it seems much slower now…I am also no longer able to reproduce the buggy behaviour.

  12. February 23, 2010 @ 12:12 am

    @Adriaan Nel: Nope, didn’t touch anything.

  13. February 23, 2010 @ 12:35 am

    @David Walsh: mmm, maybe there was something buggy on my machine then, I’ve been working (browsing,experimenting with js, php, photoshop, etc) the whole day on it…this morning just after booting, everything seems fine

  14. February 23, 2010 @ 5:13 am

    Hi David, will you be making a jQuery demo of this as well. It’s good to have only one JS-framework to add to our websites ;-) Otherwise the http-requests get too big!

  15. claudio ferreira
    February 23, 2010 @ 6:09 am

    Nice adittion to this series. I also noticed the bug Adriaan reported (on win XP FF 3.6) but today it seems ok. I can’t say exaclty what conditions generate the bug but I’m guessing it might have something to do with more then one timer running simultaneously, maybe related to page-reload but not sure. Anyway, tks again and I’m looking forward for more on this series

  16. ghazal
    February 23, 2010 @ 10:09 am

    Hi all,
    tks for this new lesson.
    Re : pb mentionned by posts above
    this line is not addressed
    var interval;
    on FF with this : var interval = 100; its OK

  17. February 25, 2010 @ 3:59 pm

    I was having the same Firefox problem a few others mentioned… a fast image followed by a slow image…

    The fix that ghazal posted above fixed it for me… thanks!

  18. March 16, 2010 @ 3:28 pm

    Hi, David

    Thanks for your work, it would be better for beginners if make your works available for zip download.

    Thanks any way

  19. sergey
    March 17, 2010 @ 11:38 am

    Hi David!
    Thanks for your work!

    I try to change images in preview section.
    I add
    var thumb = $(‘color’).getElements(‘img’); /* another div element
    and change images.each(function(img,i) to thumb.each(function(img,i)
    I show new image in preview section, but when i click to thumb image the big images is not change.
    How to change show = function(to)?

    Help please!

  20. March 21, 2010 @ 10:26 pm

    im using chrome in windows vista and its very buggy… but it works

  21. louise
    April 27, 2010 @ 12:54 am

    @ghazal: I tried that one. Doesn’t change anything in FF3.6 Whenever I am using the thumbnail navigation the slideshow still gets a bit jumpy.

  22. louise
    April 27, 2010 @ 1:28 am

    I had the same problem with FF3.6

    Since the issue just occured whenever I used the thumbnails to navigate, I tried to remove the start()-Event from the function there. It solved the problem for me.

    Now it works just fine, even after navigating with the thumbs.

  23. marcel rijs
    May 18, 2010 @ 5:34 am

    Great script. I’d really love to use this on my site but I have a question: I’m trying to implement two slideshows on one page and only the first one seems to be working. On the second one it just shows the image and nothing else – no thumbnails and no captions. I’ve tried cloning the javascript section with a different name for the div slideshow-container, but that doesn’t help either. Is there something more I should think of, or is it impossible to use this twice on one page?

  24. July 17, 2010 @ 5:24 am

    @Zinco: hehehhehe a href=”image” rel=”lightbox” , to the big image :D

  25. warren
    August 12, 2010 @ 7:58 am

    Hey how can you slow it down so that it blends into the next image a little slower?

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!