Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






Cross-Browser Animation

by Dave Thau and Apple Developer Connection
05/24/2002

The fundamental idea behind animation has been around for a long time: when a group of images are presented quickly, the series of images seems to form a single moving picture. One of the first examples of this effect was the thaumatrope, a gizmo created by Paul Roget in 1828. A thaumatrope is a disk with a pole or string attached so the disk can be twirled. Each side of the disk contains an illustration, and twirling the disk merges the two illustrations, making it seem that there's only one image. If the disk has a bird on one side and a cage on the other, twirling the disk gives the illusion that there's just one image: a bird in a cage.

Animation on the web works in a similar way. In the Web's early days animators could only use proprietary systems, like Shockwave, or animated GIF files. JavaScript expanded the animator's repertoire to include rapid GIF swapping. Swapping GIFs with JavaScript makes for quicker downloads than proprietary systems and provides more flexibility than animated GIFs.

Dynamic HTML (DHTML) provides a new range of ways to animate a page. DHTML can animate both text and images and animations can move throughout the browser window, instead of being anchored in one spot. Unfortunately, DHTML can be tricky because of differences between browsers.

This article will cover the basics of cross-browser animation. You'll learn how to animate text and images. Plus you'll see how to move HTML elements around the screen. After you've finished reading this article, you should be able to add cross-browser compatible DHTML animations to your web pages.

Resizing Images

Many web pages make use of an image that resizes with a mouseover event. You can use this technique to make a button jump out or make a small image bigger and easier to see. Instead of using an animated gif, which can have a large file size, or using image swapping, which means preloading images, you can resize an image with DHTML

In IE4.0+ and NN 6.0+, resizing an image is quite simple. Change the height and width properties of the image:

document.my_image.height = "100px";
document.my_image.width = "200px";

Netscape 4.0 doesn't let you change the height and width properties using JavaScript, so instead, it's best to put the image in a DIV and then use JavaScript to rewrite the contents of the DIV:

document.the_div.document.write("<img src='one.jpg' width='400' height='400'>");
document.the_div.document.close();

Related Reading

Designing with JavaScript
Creating Dynamic Web Pages
By Nick Heinle, Bill Pena

The first line writes the contents to the DIV. The second closes the document, which forces the sometimes-reticent Netscape to write your change to the Web page.

Steady Growth

The lines above show you how to change an image from one size to another, but that's not really animation. If you want the image to slowly grow from one size to another, instead of changing in one big jump, you have to use a more animation-like technique.

You want to change the image a small amount, then wait a very short period, then change the image another small amount. To do this in JavaScript, write a function which changes the image a little bit, and then uses a command called setTimeout() to call the function again at some point in the future. When the function is called again at that future time, the image is changed again, and the setTimeout() sets the function to be called yet again at some point in the future. This timed loop animates the image. The quantity of time between calls to the function determines the speed of the animation.

The setTimeout() function works like this:

var my_timeout = setTimeout("someFunction();", some_duration_in_milliseconds);

The setTimeout() function's first parameter determines the name of the function you want called sometime in the future. The second parameter sets the duration you want to wait in milliseconds (there are 1000 milliseconds in a second). So, if you want to call a function 2 seconds in the future, the second parameter should be 2000.

Notice that I've set a variable called my_timeout in the above function. JavaScript will refer to the entire setTimeout() function through this variable. If you want to stop the timeout from happening, you can use the clearTimeout() function and refer to the my_timeout variable:

clearTimeout(the_timeout);

Here's an example of a function that resizes an image and then calls itself using setTimeout():

function growImage()
{
  document.my_image.width = parseInt(document.my_image.width) + 10;
  document.my_image.height = parseInt(document.my_image.height) + 10;

  if (parseInt(document.my_image.width) < 200) 
  {
    my_timeout = setTimeout("growImage();", 100);
  }
}

The first two lines in the function resize the image in IE4+ and NN6+. The if-then statement sets a timeout to call the growImage() function in a tenth of a second as long as the width of the image hasn't exceeded 199 pixels. Note that I used parseInt() when getting the image dimensions. When you read the width of an image, some browsers return something like "50px". This could make for a problematic equation when added to the number 10. The parseInt() function grabs the first integer it sees in the string so you can be sure the image's width and height properties will be set to numeric values.

Take a look at the growing button demo and its source code to see a cross-browser version of image resizing.

Growing Across Browsers

The growing button demo contains some cross-browser compatibility code that's worth studying. Notice that I've put the image inside a DIV:

<div id="justforNS4" style="position:absolute;top:50;left:5;">
<a href = "#" onClick="alert('thanks!');">
<img src="button.gif" name="the_button" border="0"></a>
</div>

I did this because Netscape 4.0 does not allow dynamic resizing of images. In Netscape 4.0, I need to change the image by rewriting the contents of this DIV. Other browsers are easier to work with. You can simply change the height and width properties of the images. Here's the function which makes the image grow on a mouseOver:

function makeBig()
{
  var the_image;

  // if this is NN6 or IE4+
  if (document.documentElement || document.all) 
  {
    the_image = document.the_button;
    the_image.height = the_image.height + 2;
    the_image.width = the_image.width + 2;
  } 
  else if (document.layers)  // NN4
  {

    the_image = document.justforNS4.document.the_button;
    var new_width = the_image.width + 2;
    var new_height = the_image.height + 2;
   
    var write_string string = "<img src='button.gif' border='0' " +
       "width = '" + width + "' height = '" + height + "'>";    

    document.justforNS4.document.writeln(write_string);
    document.justforNS4.document.close();
  }

  if (parseInt(the_image.height < 110)
  {
    setTimeout("makeBig();", 10);
  }
}

First the function checks to see what image-changing method it needs to use: changing the image size for W3C DOM compliant browsers and IE4+, or rewriting the DIV for Netscape 4. Browsers that comply with the W3C DOM (Netscape 6.0+, IE 5+) recognize the document.documentElement property, and all IE4+ browsers recognize the document.all property, so the line

if (document.documentElement || document.all)

will catch all browsers that let us resize the image. If the browser doesn't recognize document.documentElement or document.all, the script checks to see if the browser recognizes document.layers, which is a Netscape 4 property. If so, the code rewrites the contents of the DIV.

After the image size has been changed, the function checks to see if the image has become too big. If its height is less than 110 pixels, the function uses setTimeout() to call itself in 10 milliseconds.

Pages: 1, 2, 3

Next Pagearrow