Submit your widget

jQuery fullscreen background image slideshow

Created 12 years ago   Views 18886   downloads 3012    Author marcofolio
 jQuery  fullscreen background image slideshow
View DemoDownload
64
Share |

With the help of some small HTML, nifty CSS and loads of jQuery, we're able to create an animated fullscreen background image slideshow.

You can easily change the script by changing some variables. It also features image preloading and keyboard navigation (try pressing the numeric keys). The background images have a width of 2000px, just to cover most of the currently used screen resolutions.

HTML

Since the page is extremely dynamic, the HTML is very empty (everything is added by jQuery). We do need some handles to inject to, so this is everything we need.

<div id="navigationBoxes">
   <!-- Navigation boxes will get injected by jQuery -->  
</div>
 
<div id="pictureSlider">
   <!-- Pictures will be injected by jQuery -->
</div>

The #navigationBoxes is a container for the navigation boxes, and the #pictureSlider is the container for the background images. That's all the HTML we'll statically need for this script! Now let's dive into some CSS.

CSS

Below, you'll find a part of the CSS I created for this effect. Take note, it isn't complete (dive into the source code to see it fully). I've only selected some key properties, just to show you what's going on.

/* Hide scrollbars */
body { overflow:hidden; }
 
/* Pictures will have a fixed width/height, and pushed to the back */
#pictureSlider div {
   height:1000px; width:2000px; position:absolute; z-index:-999;
}
 
/* Since we have several navigation boxes, we'll need to use a class (not ID) */
.navbox {
   width:450px; height:300px; position:absolute; left:0px; top:50px;
}
 
/* The navigation for each navigation box is a list */
.navbox ul {
   list-style:none; position:absolute; right:10px; top:10px;
}
.navbox ul li {
   display:inline; cursor:pointer;
}
.navbox ul li a {
   display:block; float:left; background-image:url("../images/nav_btns.png");
   color:#eee; font: bold 14px Helvetica, Arial, Sans-serif; line-height:18px;
}
.navbox ul li a:hover {
   background-position:bottom; color:#000;
}
 
/* Special class for the link when the current navigation box is selected */
.navbox ul li a.active {
   color:#777;
}
 
/* CSS styling for the navigation box text */
.navbox h2 {
   font: bold 40px Helvetica, Arial, Sans-serif;
}
.navbox p a {
   text-decoration:none;  text-transform:uppercase; letter-spacing: 10px; color:#eee;
}
.navbox p a:hover {
   border-bottom:1px dotted;
}
.navbox p.bottom {
   position:absolute; bottom:5px; right:5px;
}

Nothing extremely hard going on over here (just take note of the width and height of some boxes, and the overflow). Now let's dive into the more interesting part: the jQuery.

jQuery

Now that we have the backbone of the page (HTML) and some of the styling is complete (CSS), let's add some interactivity using jQuery. I'll take you through this script I created (comments are already added) and explain what it does. First, we'll need some variables that we can use as settings for the page. These are the ones we need:

// Speed of the animation
var animationSpeed = 600;
 
// Type of easing to use; http://gsgd.co.uk/sandbox/jquery/easing/
var easing = "easeOutCubic";
 
// Variable to store the images we need to set as background
// which also includes some text and url's.
var photos = [ {
      "title" : "Aperture",
      "cssclass" : "cam",
      "image" : "bg_cam.jpg",
      "text" : "In optics, an aperture is a hole or an opening through TRIMMED",
      "url" : 'http://www.sxc.hu/photo/1270466',
      "urltext" : 'View picture'
   },
   // More "Photo" objects can be added
];
 
// 0-based index to set which picture to show first
var activeIndex = 0;
 
// Variable to store if the animation is playing or not
var isAnimating = false;

Take note of the photos array, which contains several Photo objects. You can add more, the script will detect them automatically. Also check the property names of the Photo objects, since we'll need to use them later.

As a matter of fact, we're going to use those properties already to create the navigation boxes. Since we need to add several navigation boxes (one for each image), I found the jQuery Templates plugin very useful. It iterates over the photos, applies the specified template, and appends it to another DOM object.

 
// Add the navigation boxes
$.template("navboxTemplate", "<div class='navbox ${cssclass}'>
   <ul></ul>
   <h2>${title}</h2>
   <p>${text}</p>
   <p class='bottom'><a href='${url}' title='${title}'>${urltext}</a></p>
</div>");
$.tmpl("navboxTemplate", photos).appendTo("#navigationBoxes");

I found this plugin to be working great, and to do exactly what I wanted.

As you can see, the template adds an empty ul to the navigation box. We'll need to add the actual (numeric) navigation there. We'll use some extra jQuery to do so. At this point, we're already iterating the photos array, and we pre-load the images as well.

 
// Add the navigation, based on the Photos
// We can't use templating here, since we need the index + append events etc.
var cache = [];
for(var i = 1; i < photos.length + 1; i++) {
   $("<a />")
      .html(i)
      .data("index", i-1)
      .attr("title", photos[i-1].title)
      .click(function() {
         showImage($(this));
      })
      .appendTo(
         $("<li />")
            .appendTo(".navbox ul")
      );
         
   // Preload the images
   // More info: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript
   var cacheImage = $("<img />").attr("src", "images/" + photos[i-1]);
   cache.push(cacheImage);
}

When you click each item, it'll call the showImage function (we'll create it in the next step). Also note the index of each element will be passed on as a data attribute (not using HTML5 data-* attributes here). But first, before we create the showImage function, we need to make some final adjustments to the DOM:

 
// Set the correct "Active" classes to determine which navbox we're currently showing
$(".navbox").each(function(index) {
   var parentIndex = index + 1;
   $("ul li a", this).each(function(index) {
      if(parentIndex == (index + 1)) {
         $(this).addClass("active");
      }
   });
});
   
// Hide all the navigation boxes, except the one from current index
$(".navbox:not(:eq(" + activeIndex +"))").css('left', '-450px');
   
// Set the proper background image, based on the active index
$("<div />")
   .css({ 'background-image' : "url(images/" + photos[activeIndex].image + ")" } )
   .prependTo("#pictureSlider");

All done with that! Now it's the user interaction we need (the click event) in order to show another image based on the selected index. I hope the following code explains itself.

//
// Shows an image and plays the animation
//
var showImage = function(docElem) {
   // Retrieve the index we need to use
   var imageIndex = docElem.data("index");
   
   startAnimation(imageIndex);
};
   
//
// Starts the animation, based on the image index
//
var startAnimation = function(imageIndex) {
   // If the same number has been chosen, or the index is outside the
   // photos range, or we're already animating, do nothing
   if(activeIndex == imageIndex ||
      imageIndex > photos.length - 1 ||
      imageIndex < 0 ||
      isAnimating) {
      return;
   }
      
   isAnimating = true;
   animateNavigationBox(imageIndex);
   slideBackgroundPhoto(imageIndex);
      
   // Set the active index to the used image index
   activeIndex = imageIndex;      
};

Maybe you wonder why these two functions can't be combined to one? We'll need the startAnimation function for the keypress events. This function calls animateNavigationBox and slideBackgroundPhoto with the imageIndex, but what do those functions do? I'm glad you asked!

 
//
// Animate the navigation box
//
var animateNavigationBox = function(imageIndex) {
   
   // Hide the current navigation box
   $(".navbox").eq(activeIndex)
      .css({ 'z-index' : '998' }) // Push back
      .animate({ left : '-450px' }, animationSpeed, easing);
      
   // Show the accompanying navigation box
   $(".navbox").eq(imageIndex)
      .css({ 'z-index' : '999' }) // Push forward
      .animate({ left : '0px' }, animationSpeed, easing);
};
   
//
// Slides the background photos
//
var slideBackgroundPhoto = function(imageIndex) {
   // Retrieve the accompanying photo based on the index
   var photo = photos[imageIndex];
 
   // Create a new div and apply the CSS
   $("<div />")
      .css(
         {    'left' : '-2000px',
            'background-image' : "url(images/" + photo.image + ")" } )
      .addClass(photo.cssclass)
      .prependTo("#pictureSlider");
 
   // Slide all the pictures to the right
   $("#pictureSlider div").animate({ left : '+=2000px' }, animationSpeed, easing, function() {
      // Remove any picture that is currently outside the screen, only the first is visible
      $("#pictureSlider div:not(:first)").remove();
         
      // Animation is complete
      isAnimating = false;
   });
};

That's all we need to create this nifty effect! As a final touch, I've added keypress navigation.

// Register keypress events on the whole document
$(document).keypress(function(e) {
      
   // Keypress navigation
   // More info: http://stackoverflow.com/questions/302122/jquery-event-keypress-which-key-was-pressed
   if (!e.which && ((e.charCode || e.charCode === 0) ? e.charCode: e.keyCode)) {
       e.which = e.charCode || e.keyCode;
   }
      
   var imageIndex = e.which - 49; // The number "1" returns the keycode 49. We need to retrieve the 0-based index.
   startAnimation(imageIndex);
});

That's about it!

The article source:http://www.marcofolio.net/webdesign/animated_fullscreen_background_image_slideshow.html