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?
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:
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:
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.
The IMG tag takes an onmouseover event that calls the animate() function, and an onmouseout event that calls 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 code under the GNU GPL version 3.
Related Posts
- Displaying A New Image Based On Image Choices Via Checkboxes, the HTML DOM and JavaScript (30.5)
- Display A Random Image With JavaScript / DOM (28.6)
- Showing A Larger Image On Thumbnail MouseOver with JavaScript / DOM (27.5)
- Showing A Larger Image From A Thumbnail OnClick Via JavaScript / DOM (27.4)
- Loading A Specific Image Sequence On Page Refresh Via JavaScript / DOM (27.1)
The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.


Hello,
I just read through this excellent post! I’m hoping you might be able to help me figure out the HTML code I need in order to make something “similar” happen—that is a little more complicated:
I want to be able to click an image/button (onclick event?) to start an animation (the animation is 7 images that are a “machine in action”). Once the machine-in-action animation runs (7 images, remains on image#7 when finished), I want it to look like the machine created something….but, it creates a different item each time the start button is clicked/animation runs.
I believe this would be achieved by having a “random” image (from an array?) populate the area next to the machine image/animation imediately after the animation completes (which is still showing image#7).
When you click the start image/button again it should repeat the machine-animation but produce a different result (different image appears next to it this time).
This is hard to explain—but, hopefully not that hard to code!
I am REALLY stumped and would sooOOOooo appreciate any advice, code or even other resources to help me figure this out quickly. I’m a beginner—just trying desperately to figure this out…to put it in iWeb as an HTML snippet.
Thank you in advance for any help you could offer!
Trisha
@Trisha: I am happy to help you with a specific implementation of my code, including modifying it as you describe, in exchange for a wish list purchase. For more information, click the “need more help or want to say thanks” link at the top of the page.