Photo Gallery – jQuery Slide Show Player
Most photo galleries have some option to allow the user to see an automated slide show. It is a nice feature and I wanted to use jQuery to implement it in the photo gallery that I have been working on.
I started off by doing a little refactoring to support this feature. I already had the ability to click on a thumbnail and then load a high resolution version in a larger frame. This ability to show the image is contained in the following JavaScript:
// Show the new image function showImage(imageDivId) { // If there was a previously selected element // then deselect it and fade it out a bit $(".imageFrameSelected").removeClass("imageFrameSelected").fadeTo("fast", 0.67); // Get the jQuery object for the new div var jqDiv = $("#" + imageDivId); // Fade the new picture in all the way and set // it as selected. jqDiv.fadeTo("fast", 1.0).addClass("imageFrameSelected"); // Gather information that has been embedded // into the html elements. var jqElem = jqDiv.find('img'); var thumbUrl = jqElem.attr('src'); var temp = new Array(); temp = thumbUrl.split('&'); var imageUrl = temp[0]; for(var i=1;i<temp.length;i++) { // 't=1' means show the thumbnail // we want to remove this. if(temp[i]!='t=1') { imageUrl += '&' + temp[i]; } } var imageName = jqElem.attr('alt'); // Fade the current image out $(".image").fadeOut("slow", function(){ // Hook up the new image. $(this).attr("src", imageUrl).attr("alt", imageName); // Connect up the save link $("#_aSave").attr("href", imageUrl + "&d=1"); // Get other info about this image. UpdateImageInfo(imageUrl); }); // Prevent the postback click return false; }
This function takes as a parameter the element id of the div containing the image that we want to show. First notice, that I am using jQuery to greatly simplify my JavaScript code. The first couple lines in this function fades out / deselects the currently selected image and the fades in / selects the new image. This is applied to the film strip containing the thumbnail images. The function then strips out information that has been embedded into the HTML (source and name) for the new image. This information is then applied to the HTML IMG element that displays the new image. The ‘showImage’ function is not new. Now that it has been re-factored it can be reused by the slide show code.
To initiate the slide show, I have hooked up a ‘play’ button that calls the following ‘Play’ JavaScript function:
var isPlaying = false; var jsDivs = undefined; var slideShowIndex = 0; function Play() { // Load all the thumb divs into an array jsDivs = $(".outerFrame div").not(".folderFrame"); // Only do slide show if more than one slide exists. if(jsDivs.length > 1) { // Set the starting index. Use the selected image // if one has been selected. slideShowIndex = 0; for(var i=0;i<jsDivs.length;i++) { var className = jsDivs.eq(i).attr("class"); if(className.indexOf("imageFrameSelected")!=-1) { slideShowIndex = i; break; } } // Swap the play and stop buttons. $("#_aPlay").hide(); $("#_aStop").show(); // Start the show. isPlaying = true; showNextSlide(); } return false; }
This function first loads all the image divs that are not showing folders into the ‘jsDivs’ global variable. It then does a search through the ‘jsDivs’ array looking for the currently selected image. If one is found, it sets the ‘slideShowIndex’ to it or it starts the slide show at the first image in the array. The function then hides the ‘play’ button and shows the ‘stop’ button. The last two lines start the slide show playing. The ‘showNextSlide’ function is shown here:
function showNextSlide() { if(isPlaying) { // Get the div for the next image var jsDiv = jsDivs.eq(slideShowIndex); // Increment the slide count...wrap // around to the beginning if necessary slideShowIndex++; if(slideShowIndex>=jsDivs.length) { slideShowIndex = 0; } // Force the next image to be cached // to speed up the transitions. var nextDiv = jsDivs.eq(slideShowIndex); var jqElem = nextDiv.find('img'); var thumbUrl = jqElem.attr('src'); var temp = new Array(); temp = thumbUrl.split('&'); var imageUrl = temp[0]; for(var i=1;i<temp.length;i++) { if(temp[i]!='t=1') { imageUrl += '&' + temp[i]; } } $("#_image2").attr("src", imageUrl); // Show the new image. showImage(jsDiv.attr("id")); } }
This function walks through the ‘jsDiv’ array and then recycles back to the top. At the very end of the function the call to ‘showImage’ is made. There is a little trickery in the middle to load the next image into a hidden HTML IMG element. This forces the image to be pre-fetched and cached. This enhances the user experience by minimizing the transitions between the images. There is an animate GIF in place, but who wants to stare at that!
So you are probably wondering how the slide show continues. The following code is called when the page loads. This code uses jQuery to attach some JavaScript to the main image’s load event.
// Do this as early as possible $(document).ready(function(){ // Hook up an onload handler to always // fade in asynchronously load images. $(".image").load(function(){ $(this).fadeIn("slow"); if(isPlaying) { // Showing a slide...show for 5 seconds and // then load the next one. setTimeout(function(){ showNextSlide();}, 5000); } }); });
The code that is attached looks at the ‘isPlaying’ global variable and determines if the next image should be queued up. Each image is displayed for 5 seconds. The stop button is wired up as follows:
function Stop() { // Swap the play and stop buttons. $("#_aPlay").show(); $("#_aStop").hide(); // Stop the show. isPlaying = false; return false; }
It simply restores the UI and then sets the global ‘isPlaying’ variable to false. A working demo of this can be found here.
This is awesome. I’m an amateur photographer that has recently gotten into competitions and such. People are starting to ask for my portfolio, and I had no clue how to start. This was great!