28 November 2004

Javscript Image Fade with Cycling

I wanted a fader of images on the top of my site. I looked around and decided Javascript would do the job as I didn’t want to put Flash on my site.

After some digging, and hacking, and digging and hacking, I beat the script into humble submission.

Onload image fades without Flash

Fade Test

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.

See finale

 

Comment



note: you can only submit after you hit preview


nuff-respec is a weblog written by daniel bulli a senior web programmer in boston, ma.
more >

contact | resume | profile

recently :::

diversions :::

beSlimed - Mootools game
Cool little game done in my favorite javascript library...
First Magazine
A Jamaican Magazine on the web ... very clean ... now i need to explore the articles ...
The Afflicted Yard
Love to see when there is Jamaican stuff out there... nice thoughts and clean design ... just don't look on the source code ...
BugMeNot
What a wonderful service of passwords for sites that want pointless registrations...
you still want more »