After some digging, and hacking, and digging and hacking, I beat the script into humble submission.
Onload image fades without Flash
They both did a great job, but none quite where I wanted it. Firstly I wanted to cycle images and have a way for the user to stop the animation, but they seemed to go haywired for several images in IE. SO I put them in… and started hacking away.
Firstly I was using this for the main image on my site, so (call it lazy), I just declared everything I needed globally versus passing around containers.
Firstly the HTML and CSS
h1#container {
background : #fff url(img1) no-repeat left top;
height : 170px;
font-size : 1px;
width : 510px;
}
h1#container span {
position: absolute;
left: -2000px;
top: 0;
}
img#target {
width : 510px;
height : 150px;
}
<h1 id="container">
<span>nuff-respec:::</span>
<img id="target" src="img1.gif" alt="" ...
width="1" height="1" border="0" />
</h1>
No rocket science here, but note I did set the old school height and image to “1” as I did not want it to show, when users look on page without styles. I also set both background of container and image to the same image. See how this looks
Now some global variables in javascript.
//boolean: whether or not we are fading
var doingFade = true;
//use as a handle on the timeout loop
var timeout;
//variable to hold global opactiy
var globalOpacity = 0;
var imageNames = “img1.gif img2.gif img3.gif”.split(” “);
//next image index to be faded
var indexValue = Math.floor(Math.random() ...
*imageNames.length-1)+1;
//variables for container/controller/target
var containerID = ‘container’;
var targetID = ‘target’;
var controlID = ‘control’;
var container = null;
var target = null;
var control = null;
Everything should be self explanatory, note that a random image of only 3 images will see allot of repeat.
Now we add an event to trigger the start of fading at the bottom of html, I will not explain addEvent, check out the source: scott andrew
<script type="text/javascript" language="javascript">
// <![CDATA[
addEvent(window, 'load', startPhoto);
// ]]>
</script>
Now a function… woohoo !
function startPhoto()
{
if (!document.getElementById) return;
//set references to container && target ** a href
container = document.getElementById(containerID);
target = document.getElementById(targetID);
control = document.getElementById(controlID);
setalpha(0) ;
timeout = window.setTimeout("nextPhoto()", 4000);
}
A lame function, but does the job.
If browser doesn’t support “getElementById” we don’t continue.
Next we obtain global references to container, target, and controller.
We then set the alpha of target to 0 (**setalpha** again I will not explain as it covered in source reference).
This is one of the main differences, I do not use hidden and visible to switch out images!
After all of that we set a timeout to start image fading in 4 seconds… 1, 2, 3, 4 …
function nextPhoto()
{
if (!document.getElementById) return;
// only one transition at a time, please
clearTimeout(timeout);
//flip image and container
switchContainer();
//load next image
target.src = imageNames[indexValue];
//get new index differnet from current
var newvalue = indexValue;
while(newvalue == indexValue)
{
newvalue = Math.floor(Math.random()* ...
imageNames.length);
}
indexValue = newvalue;
//fade image in
timeout = window.setTimeout(“reveal(‘0’)”, 500);
}
function switchContainer()
{
if (!document.getElementById) return;
//make container background current image
container.style.backgroundImage = ...
‘url(’ + target.src + ‘)’;
//make image 0
setalpha(0) ;
}
Firstly we clearTimeout just to make sure only one timeout is happening at a time.
switchContainer() :: We then make the background image the same as the target img, and then make the target alpha of 0.
We load the next image into the target which now has an alpha of 0.
Afterwards we loop and get a new index that is different from the current index.
Finally we call reveal() which fades the img in.
function reveal(opacity)
{
if (!document.getElementById) return;
if (document.getElementById && opacity <= 100 )
{
setalpha(opacity);
opacity += 5;
//store globally fo restart
globalOpacity = opacity;
//fade next step
timeout = window.setTimeout …
(“reveal(”opacity“)”, 100);
}
else
{
//we are done .. load next photo in 5 seconds
timeout = window.setTimeout(“nextPhoto()”, 5000);
switchContainer();
}
}
Reveal sets the opacity in increments of 5 every 1/100 of a second, until opacity is 100.
Once we get to the desired opactiy (100), we set timer to start next image fade in 5 seconds. As insurance we make sure both images are the same.
Now for the final tweak.
function stopPhoto()
{
if (!document.getElementById) return;
if(doingFade)
{
//stopfade
control.innerHTML = "start fade";
clearTimeout(timeout);
}
else
{
//start fade from where we left off
control.innerHTML = "stop fade";
timeout = window.setTimeout ...
("reveal("+globalOpacity+")", 100);
}
//invert variable
doingFade = !doingFade;
}
We call this function when we want to stop and start the fade. If we are currently in fade mode we just clear the timer, otherwise we create a new timer.
We also change the text of href, to give user feed back of which action they want to do.