Create a Simple Automated Slideshow

By Rob Gravelle

Create a Simple Automated Slideshow

I was looking to present a simple looping slideshow on my website the other day, and it just seemed that all of the plugins I came across were too bulky for my trivial purpose, so I turned my attention to stand-alone solutions. In the end, I found that jQuery was all that I needed to accomplish what I wanted to. In today's article, I'll show you how I did it.

Defining the Images

Some people include the image list in the JavaScript source, but I prefer to keep them within the HTML realm, since they are part of the page's content. I was too lazy to figure out all of the image dimensions, so that is done in the JS. My original list contains a number of t-shirts with religion-themed graphics and text. Stuff like "Worship me or I Will Torture You Forever! Have Nice Day. BFF - God". You might not think of this as being an especially funny subject, but with the right lighthearted mindset, religion can be hilarious fodder. Just ask Monty Python. Nonetheless, today's demo slideshow is about a much less incendiary subject, namely cars. 

<div id="slideshow">
  <div>
    <img src="mustang.jpg" alt="mustang.jpg"><br>
    A newer Mustang.
  </div>
  <div>
    <img src="camaro.jpg" alt="camaro.jpg"><br>
    A modern Camaro.
  </div>
  <div>
    <img src="classic.jpg" alt="classic.jpg"><br>
    An oldie but a goodie!
  </div>
  <div>
    <img src="classic2.jpg" alt="classic2.jpg"><br>
    More old cars.
  </div>
  <div>
    <img src="video_game_car.jpg" alt="video_game_car.jpg"><br>
    A good renering of a classic race car.
  </div>
</div>

The CSS is really quite minimal and just sets the container DIV dimensions, adds padding between the top and left page margins and the image, and surrounds the image with a border and shadow.

#slideshow {
    position: relative;
    width: 300px;
    height: 510px;
    padding: 10px;
}

#slideshow > div {
    position: absolute;
    top: 10px;
    left: 10px;
}
#slideshow > div > img {
    border: 2px solid white;
    box-shadow: 0 0 20px white;
}

Appended to the bottom of the document, the JS kicks in only after all of our images have been defined. The first line hides all the image DIVs so that we can show them one at a time within the slideshow. Then, setInterval() is employed to iterate over the images at a pace of every 5 seconds. It invokes the anonymous function that fades the current image out, proceeds to the next sibling, fades it in, and appends it to the slideshow container element. Notice the use of the end() function that returns the this pointer to an earlier state. Without it, the next call to fadeOut() does not work as expected, leading to the images being piled on top of each other.

$("#slideshow > div").hide();

setInterval(function() {
  $('#slideshow > div:first')
    .fadeOut(1000)
    .next()
    .fadeIn(1000)
    .end()
    .appendTo('#slideshow');
},  5000);

Here is the result on Codepen.

Works quite well, except for the fact that the slideshow starts with the second image in the list. That's because the current image is faded out before the next one is faded in. There is no code to show the first image. That is corrected in the next section...

Centering Images

Centering different size images dynamically is no walk in the park, mainly because this depends on the size of the images, which are not known prior to loading. The solution to that particular issue is to create a new Image object and assign its src to that of the image element. That causes the browser to download the image and thereby assign its dimensions:

jQuery.fn.setDivSize = function(extraHeight, extraWidth) {
  var img = new Image();
  img.src = this.children('img').attr('src');
  //the extra height and width are to accommodate
  //the text below the images.
  this.height(img.height + extraHeight)
      .width (img.width  + extraHeight);
  return this;
}

The Centering Function

Here's the function that centers an image relative to its parent or containing window based on a boolean argument (true is for parent):

jQuery.fn.center = function( parent ) {
    parent = $( parent ? this.parent() : window );
   
    this.css({
        "position": "absolute",
        "top":  (((parent.height() - this.outerHeight()) / 2) + parent.scrollTop()  + "px"),
        "left": (((parent.width()  - this.outerWidth())  / 2) + parent.scrollLeft() + "px")
    });
    return this;
}

Putting It All Together

This time, I included some setTimeouts to give elements a chance to render completely. Otherwise, I noticed inconsistencies around the image edges.

$(function() { 
  setTimeout(function(){
    //display the first image
    $('#slideshow > div:first')
      .setDivSize(30, 40)
      .center(false)
      .fadeIn(1000);
   
    //loop through the remaining images
    setInterval(function() {
      $('#slideshow > div:first')
        .fadeOut(1000)
        .next()
        .setDivSize(30,40)
        .center(false)
        .fadeIn(1000)
        .end()
        .appendTo('#slideshow');
    },  5000);
  }, 500 );
});

Here is the updated slideshow on Codepen and you can see the original slideshow here if you're interested.

Conclusion

In a future instalment, we'll add some controls to the slideshow and implement cross fading.

Rob Gravelle

Rob Gravelle resides in Ottawa, Canada, and is the founder of GravelleWebDesign.com. Rob has built systems for Intelligence-related organizations such as Canada Border Services, CSIS as well as for numerous commercial businesses.

In his spare time, Rob has become an accomplished guitar player, and has released several CDs. His band, Ivory Knight, was rated as one of Canada's top hard rock and metal groups by Brave Words magazine (issue #92) and reached the #1 spot in the National Heavy Metal charts on Reverb Nation.



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •  
  •  
Thanks for your registration, follow us on our social networks to keep up-to-date