Ever since Flipboard first came to the iPad, I really liked its cover page slideshow of images. In this post I’m going to show you how I’ve replicated a similar visual experience.

Live Demo / Download Now / Documentation

The live demo shows a slideshow of images associated with my most recent tweets. The download includes the source code and an example with National Geographic images.

The remainder of this post explains how I got to the end result. My initial gut reaction was to first google around for a jQuery plugin that displays images in fullscreen mode, and that’s when I found a great library called backstretch. The backstretch library did the job of scaling images to fit the browser window, but I had to modify it somewhat for it to work as a slideshow that I envisioned.

Following is a walkthrough of my alterations and tweaks to the backstretch library.

Step 1. Creating a slideshow

$.slideshow = function(images, options) { var settings = { slideshowSpeed: 3000 } // Extend the settings with those the user has provided if(options && typeof options == "object") $.extend(settings, options); var currentImage = 0; function slideshow() { if (currentImage >= images.length) { currentImage = 0; } $.backstretch(images[currentImage], options, function() { setTimeout(slideshow, settings.slideshowSpeed); } ); currentImage += 1; } // start slideshow $(document).ready(slideshow); }

Starting the slideshow is a simple call to slideshow() and passing in an array of images.

$(document).ready(function() { $.slideshow(["image1.jpg", "image2.jpg"]); });

Step 2. Image animation using jQuery

function _showAndAnimate(initialTop, initialLeft, initialWidth, initialHeight, animateProperties, callback) { bgCSS = {left: 0, top: 0} // Override bgCSS with inital top and left if(settings.centeredY) $.extend(bgCSS, {top: initialTop, left: initialLeft}); // Set initial width, height, top and left $("#backstretch img:last").width(initialWidth).height(initialHeight).css(bgCSS); $("#backstretch img:last").show().animate( animateProperties, settings.speed, function(){ // Remove the old images, if necessary. container.find('.deleteable').remove(); // Callback if(typeof callback == "function") callback(); } ); }

Step 3. Fullscreen zoom animation

// Adjust bg and apply zoom animation function _adjustBGAndZoom(callback) { try { // Zoom offset is an extra 250px on the top-left and bottom-right, the total zoom offset being twice that var zoomOffset = 250; var totalZoomOffset = zoomOffset * 2; // Need to calculate these values for image animation var initialWidth, initialHeight, initialTop, initialLeft = 0; var finalWidth, finalHeight, finalTop, finalLeft = 0; // Choose best effect based on browser window size and image ratio if ((rootElement.width() / imgRatio) >= rootElement.height()) { // Calculate initial width (image width + total zoom offset) // and initial height (inital width divided by image ratio) initialWidth = rootElement.width() + totalZoomOffset; initialHeight = (initialWidth / imgRatio); // Calculate difference between initial height and (image width / ratio) var heightDiff = initialHeight - (rootElement.width() / imgRatio); // Calculate offset - ((initial height - image height - height delta) / 2) + zoom offset var bgOffset = ((initialHeight - rootElement.height() - heightDiff) / 2) + zoomOffset; // Calculate initial top, initial left, final width, height, top and left initialTop = "-" + bgOffset + "px"; initialLeft = "-" + zoomOffset + "px"; finalWidth = rootElement.width() + 'px'; finalHeight = (initialHeight - heightDiff) + 'px'; finalTop = '-' + (bgOffset - zoomOffset) + 'px'; finalLeft = '0px'; } else { // Calculate initial height (image height + total zoom offset) // and initial width (inital height times image ratio) initialHeight = rootElement.height() + totalZoomOffset; initialWidth = (initialHeight * imgRatio); // Calculate difference between initial width and (image height * ratio) var widthDiff = initialWidth - (rootElement.height() * imgRatio); // Calculate offset - ((initial width - image width - width delta) / 2) var bgOffset = ((initialWidth - rootElement.width() - widthDiff) / 2) + zoomOffset; // Calculate initial top, initial left, final width, height, top and left initialTop = "-" + zoomOffset + "px"; initialLeft = "-" + bgOffset + "px"; finalWidth = (initialWidth - widthDiff) + 'px'; finalHeight = rootElement.height() + 'px'; finalTop = '0px'; finalLeft = '-' + (bgOffset - zoomOffset) + 'px'; } // Show image and start animation, callback called once animation is done _showAndAnimate(initialTop, initialLeft, initialWidth, initialHeight, {height: finalHeight, width: finalWidth, top: finalTop, left: finalLeft}, callback); } catch(err) { // IE7 seems to trigger _adjustBG before the image is loaded. // This try/catch block is a hack to let it fail gracefully. } }

Step 4. Fullscreen slide animation

// Adjust bg and apply slide down or left to right animation function _adjustBGAndSlideDownOrLeftToRight(callback) { try { // Slide offset is an extra 250px var slideOffset = 250; // Need to calculate these values for image animation var initialWidth, initialHeight, initialTop, initialLeft = 0; // Choose best effect based on browser window size and image ratio if ((rootElement.width() / imgRatio) >= rootElement.height()) { // Slide down effect // Calculate initial width (browser window width) // and initial height (inital width / image ratio) initialWidth = rootElement.width(); initialHeight = (initialWidth / imgRatio); // Calculate offset, initial height - browser window height or slideOffset, whichever is smallest var bgOffset = (initialHeight - rootElement.height()); if (bgOffset > slideOffset) { bgOffset = slideOffset; } initialTop = "-" + bgOffset + "px"; initialLeft = "0px"; } else { // Slide left to right effect // Calculate initial height (browser window height) // and initial width (inital height times image ratio) initialHeight = rootElement.height(); initialWidth = (initialHeight * imgRatio); // Calculate offset, initial width - browser window width or slideOffset, whichever is smallest var bgOffset = (initialWidth - rootElement.width()); if (bgOffset > slideOffset) { bgOffset = slideOffset; } initialTop = "0px"; initialLeft = "-" + bgOffset + "px"; } // Show image and start animation, callback called once animation is done _showAndAnimate(initialTop, initialLeft, initialWidth, initialHeight, {height: initialHeight + 'px', width: initialWidth + 'px', top: '0px', left: '0px'}, callback); } catch(err) { // IE7 seems to trigger _adjustBG before the image is loaded. // This try/catch block is a hack to let it fail gracefully. } }

Step 5. Slideshow with the animation picked at random

function _adjustBGAndShowWithRandomAnimation(callback) { // Randomly set animationFlag to either 0, 1 or 2 or 3 // Note: probability is 50% that it will be a zoom animatiob, // 50% it will be slide animation var animationFlag = Math.floor(Math.random() * 4); if (animationFlag <= 1) { _adjustBGAndZoom(callback); } else if (animationFlag == 2) { _adjustBGAndSlideDownOrLeftToRight(callback); } else if (animationFlag == 3) { _adjustBGAndSlideUpOrRightToLeft(callback); } }

The original call to _adjustBG within the _init method is replaced by the above method.

function _init() { ... /* Orginal Fade animation _adjustBG(function() { ... } */ // Call random animation instead _adjustBGAndShowWithRandomAnimation(callback); ... }

Feel free to download the code and play around with the included example, which displays a slideshow of eye-catching images from National Geographic.

About me: http://99layers.com/chico

Twitter: @​ccharlesworth