A Javascript + CSS replacement for Flash photo fading slideshow. Inspired by Richard Rutter's image fade demonstration.
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 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.
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
}
}
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.
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.
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.
This work is licensed under a Creative Commons Attribution 2.5 License.