Swapping An Image From A Non-Animated GIF To An Animated GIF Via JavaScript / DOM

Recently asked on Yahoo! Answers:

I have created a .gif for a webpage how do I get it to animate only when the mouse pointer is on top of it?

I have created a .gif for a webpage how do I get it to animate only when the mouse pointer is on top of it?

Do you have a link to a page which can guide me here.

I have frontpage etc

This is fundamentally a mash-up of previous topics I have posted on swapping images on mouseover. Basically, it’s three steps:

  • Create the animated GIF;
  • Create a second GIF, that is only the first frame of the animated GIF;
  • Put together some JavaScript and HTML that swaps the images on mouseover / mouseout.

Or, we could simply let JavaScript handle the animations, and just use a series of images in sequence. I’ll demonstrate both approaches. As always, a link to a functioning demo appears at the end of this entry.

Step 1: The Basic Image Swap JavaScript Functions

Swapping an image in JavaScript / DOM manipulation is simple: We simply have JavaScript change the src (source) attribute of the given image.

To do that, we need to know two things: the ID of the image we want to change, and the new source for the image.

We pass those as arguments to the script, which first gets the image we want to change via getElementById, then assigns that image a new src based on the second argument.

function swapImage(imgID, imgSrc) {
	var theImage = document.getElementById(imgID)
	theImage.src = imgSrc;
}

Yes, it’s that simple.

But as I’ve previously noted, unless you pre-load the image(s) you’re going to use on the mouseover, there will be a delay between the mouseover and when the new image appears. To resolve that problem, we create a preload script that accepts a list of image paths, and loads them all into the page cache without actually displaying them.

Notice that we don’t need to explicitly state all the parameters we’re going to pass to this function. In JavaScript, arguments to a function can be called as an array, meaning you don’t need to know how many arguments there are, or what those arguments are (objects, strings, integers, etc.), in order to work with all of them; we can simply iterate through the arguments as we would any array.

function preLoadImages() {
	for(var i = 0; i < arguments.length; i++) {
		var tmpImage = new Image();
		tmpImage.src = arguments[i];
	}
}

Step 2: Prepare The HTML For Swapping

The HTML we use to make the image swap needs three elements:

  • A unique ID for the image, so the JavaScript function knows to swap this image;
  • A mouseover event handler that will call the swapImage function and replace the default image with our animated GIF;
  • A mouseout event handler that will call the swapImage function again, replacing the animated GIF with the default image.

So, here’s how our IMG tag will look with all those attributes added:

<img id="imgToSwap" src="elena.gif" alt="animated gif" onmouseover="swapImage('imgToSwap', 'elena-animated.gif');" onmouseout="swapImage('imgToSwap', 'elena.gif');" />

Notice that the image’s initial src attribute is set to be the non-animated image.

We also need to add the preload function to the body’s onload event handler. Again, we add as arguments all the animated GIFs our page will use as swaps:

<body onload="preLoadImages('elena-animated.gif');">

And that’s all there is to it. You can see this in action here:

http://www.dougv.com/demo/js_animated_imgswap/

To use it, simply download the page to your computer and copy and paste the JavaScript to your page.

Example 2: A JavaScript / DOM Animated Sequence That Stops On MouseOut

The problem with the previous example, as you may have noted, is that when you mouse out, you go back to the first frame — which comes off as somewhat abrupt. How can we fix that so that the animation stops when we mouse out but resumes from the last frame when we mouse over again?

Simple: We’ll let JavaScript do the animating for us, by using setTimeout to continuously change the source of the image in the same sequence as the individual frames of the animation. And, as an added benefit, we can use JPGs or PNGs for this method — in effect, making animated JPGs or animated PNGs!

Step 1: Some Global Variables

We need two global variables to make this script work: an array to hold all of our animation images, in order; and an integer that will store the current index of the array — that is, the number of the array cell that is the source of the image at the moment.

var imgArray = new Array();
var imgIndex = 0;

Step 2: The JavaScript Image Preload Script Revisted

We’ll again use a preloader for this script, but we’ll also populate the global array with it. So, when we write the BODY tag’s onload event handler, we’ll put in the names of our animation images, in the order they should appear in the animation (that is, frame 1 first; frame 2 second, etc.).

function pageLoad() {
	for(var i = 0; i < arguments.length; i++) {
		imgArray[i] = arguments[i];
		var tmp = new Image();
		tmp.src = arguments[i];
	}
}

Step 3: The Animation Function

To animate our JPGs, we simply get the image via getElementById, then assign it a new src attribute from the global array. We then increment the index counter by one, and reset it back to 0 if that index goes out of range.

Finally, we use setTimeout to call the script over and over again; in our case, we’ll change images every half-second.

function animate() {
	var theImage = document.getElementById('imgToSwap');
	theImage.src = imgArray[imgIndex];
	imgIndex = imgIndex + 1;

	if(imgIndex == imgArray.length) {
		imgIndex = 0;
	}
	timerID = setTimeout('animate()', 500);
}

Step 4: The Stop Function

Finally, we need a way to stop the images from changing; that’s as simple as calling clearTimeout on the timer we created in the animate() function.

function stop() {
	clearTimeout(timerID);
}

Step 5: The HTML

Two quick HTML tag changes make everything work. First, we add the images to the pageLoad function’s arguments, and call that from the onload event of the BODY tag.

<body onload="pageLoad('elena1.jpg', 'elena2.jpg', 'elena3.jpg', 'elena4.jpg', 'elena5.jpg', 'elena6.jpg')">

The IMG tag takes an onmouseover event that calls the animate() function, and an onmouseout event that calls stop().

<img src="elena1.jpg" alt="animated gif" id="imgToSwap" onmouseover="animate()" onmouseout="stop()" />

And that’s all there is to it. You can see a working demo here:

http://www.dougv.com/demo/js_animated_imgswap/example2.html

Again, to use it, just save the page to your computer, copy the JavaScript to your page and change the images as appropriate.

I distribute all code under the latest version of the Creative Commons Attribution / Share-Alike License.

Share This:
  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot
  • Facebook
  • DZone
  • DotNetKicks
  • Mixx
  • MisterWong
  • LinkedIn
  • Google Bookmarks
  • Yahoo! MyWeb
  • Windows Live Favorites
  • Print this

Leave a Reply