CSS Linked Photo Shuffler

A Javascript + CSS replacement for Flash photo fading slideshow. Inspired by Richard Rutter's image fade demonstration.

Example

Texas State Capitol

The XHTML

An image in an anchor in a div


<div id="photodiv">
  <a id="photoanchor" href="http://flickr.com">
    <img id="photoimg" src="bb3d0d6134.jpg" />
  </a>
</div>

The XHTML contains the image that will be both the first and the last image shown. The other image source values and their links are put into the javascript routine.

The Setup

The customization section lets you set up how many photos in the deck and how many times you want to run through the deck. The Href array contains links corresponding to each image.


var gblPhotoShufflerDivId = "photodiv";
var gblPhotoShufflerImgId = "photoimg"; 
var gblImg = new Array(
  "78ebdaf8bc.jpg",
  "3523869ba4.jpg",
  "fabcf2f7ce.jpg"
  );
var gblHref = new Array(
  "http://google.com",
  "javascript:alert('long way down');",
  "http://carl.camera"
  );
var gblPauseSeconds = 7.25;
var gblFadeSeconds = .85;
var gblRotations = 1;

Specify unique IDs for your image, anchor, and div. Load up the array with source paths to images to place into the rotation.

Pause seconds and fade seconds are pretty self-explanatory. I like fades to be between .75 and 2 seconds. Regardless of how long you choose to fade the image, I compute a fade call at 30fps, so even excruciatingly long fades have fairly smooth transitions.

Rotations allows you to move through the deck multiple times. It accepts a value of zero, meaning show each image in the deck then stop.

The Fade

You can hook the photoShufflerLaunch routine into your onload event by whatever means you prefer. It will load the first image from the array into the div background and pause the specified number of seconds.

When the timer pops, the image will fade to reveal the div background.



function photoShufflerFade()
{
  var theimg = document.getElementById(gblPhotoShufflerImgId);
	
  // determine delta based on number of fade seconds
  // the slower the fade the more increments needed
  var fadeDelta = 100 / (30 * gblFadeSeconds);

  // fade top out to reveal bottom image
  if (gblOpacity < 2*fadeDelta ) 
  {
    gblOpacity = 100;
    // stop the rotation if we're done
    if (gblImageRotations < 1) return;

    photoShufflerShuffle();
    // pause before next fade
    setTimeout("photoShufflerFade()",gblPauseSeconds*1000);

  } else  {

    gblOpacity -= fadeDelta;
    setOpacity(theimg,gblOpacity);
    setTimeout("photoShufflerFade()",30);  // 1/30th of a second

  }
}

The Shuffle

Then I shuffle the deck.

Once the div background is fully revealed, I pop the background image source value into the (transparent) image source attribute and set the opacity of the image to 100 percent. The image is fully opaque and completely hides the div background, which at this point, is the same photo.


function photoShufflerShuffle()
{
  var thediv = document.getElementById(gblPhotoShufflerDivId);
  var theimg = document.getElementById(gblPhotoShufflerImgId);
  var theanchor = document.getElementById(gblPhotoShufflerAnchorId);

  // copy div background-image to img.src
  theimg.src = gblImg[gblOnDeck];
  theanchor.href = gblHref[gblOnDeck];
  window.status = gblHref[gblOnDeck]; // updates status bar (optional)
  // set img opacity to 100
  setOpacity(theimg,100);

  // shuffle the deck
  gblOnDeck = ++gblOnDeck % gblDeckSize;
  // decrement rotation counter
  if (--gblImageRotations < 1)
  {
    // insert start/final image if we're done
    gblImg[gblOnDeck] = gblStartImg;
    gblHref[gblOnDeck] = gblStartHref;
  }

  // slide next image underneath
  thediv.style.backgroundImage='url(' + gblImg[gblOnDeck] + ')';
}


I set the background image to the next photo in line, and pause the specified number of seconds.

When the timer pops, the image will fade to reveal the div background. I work through the rotation the specified number of times, then show the first photo again and stop.

Caching

As my Stanford professors were wont to say, ensuring that a photo is loaded before fading to it "...is left as an exercise for the student."

Since the photos are loaded as div backgrounds for the duration of the pause, they have a few seconds to load. I haven't seen any broken images yet, but I have fairly decent bandwith capabilities at home.

Accessibility, Compatibility

In practice, I put the CSS and JavaScript into their own files. For this demo page, I've included everything together as a unit for improved portability.

License

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.