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
Pages: 1, 2, 3

Animating Text

Animating text is much like animating images. But instead of changing the height and width of an image, you'll change the fontsize of the text. In IE5+ or NN6+, you can do this:
var my_div = document.getElementById("myDiv");
my_div.style.fontSize = "36px";

Be careful when using IE5/Mac; this browser won't let you change font style information if the font is inside a positioned element. If you want to animate text on IE5/Mac, you have to make sure the text is not inside a positioned element.



Here's the code for changing the font in IE4:

var my_div = document.all.myDiv;
my_div.style.fontSize = "36px";

and in NN4:

var my_div = window.myDiv;
document.my_div.document.write("<font size = '36px'>This is my text</font>);
document.my_div.document.close();

The dancing letters demo shows this kind of thing in action (IE5+ and NN6+ only). Each letter lives in its own SPAN:

<span>h</span>

The animation goes through each SPAN and changes the fontSize in its style:

var timeout;
function dance()
{    

  var mySpans = document.getElementsByTagName("span");
  var size;
  var loop = 0;

  while (mySpans.item(loop))
  {
    size = Math.floor(Math.random() * 60) + 12;
    mySpans.item(loop).style.fontSize = size;
    loop++;
  }

  timeout = setTimeout("dance();",500);
}

The first three lines in the function declare some variables. The first value gets a list of all the SPANs on the page. Once the variables have been set, the while loop goes through the list of SPANs using the item() method. Each time through, the random() method generates a random number between 12 and 72, and the fontSize of the appropriate SPAN is changed to that number. If the getElementsByTagName() or the item() methods are unfamiliar to you, take a look at the articles on the new DOM.

Although this type of thing is relatively straightforward in IE5+ and NN6+, it's quite a bit trickier in NN4. In NN4, you have to put the word inside a DIV and rewrite the contents of the DIV as I did when resizing images. Here's a cross-browser version of the jumpy text resizing.

If you want to see the letters resize a bit more smoothly, look at the smoothly growing letters demo. You can view the source to see how it works.

Moving Pictures

So far you've seen how to animate pictures and text in place. In this section you'll learn how to move things around the screen.

A DIV can be moved by dynamically changing its left and top properties. For example, to move a DIV with an id of "myDiv" you could use the getStyleObject() function introduced in the article on hiding and showing layers to get the stylesheet of the DIV, and then change its left and top properties. One slight complication is that Netscape 4 expects these values to be numbers and will give you an error if you try to introduce strings to these properties. The other browsers expect the numbers to be strings, formatted as a number followed by "px" if the number is in pixels.

Here's an example that moves a DIV from one place to another. If you look at the source of the example, you'll see that clicking on a link triggers the jump() function, which gets the stylesheet of the DIV and moves it a bit to the left and a bit down. The critical lines for moving the DIV are:

var the_style = getStyleObject("myDiv");

var the_left = parseInt(the_style.left) + 100;
var the_top = parseInt(the_style.top) + 100;
if (document.layers)
{
  the_style.left = the_left;
  the_style.top = the_top;
}
else 
{
  the_style.left = the_left + "px";
  the_style.top = the_top + "px";
}

First, the script gets the stylesheet using the getStyleObject() function. Then it calculates the new values of the top and left coordinates of the DIV. Next, it assigns the new values to the left and top property of the DIV. If the browser viewing the page supports document.layers (Netscape 4), the script assigns new numbers to the left and top properties. If the browser is not Netscape 4, the script sticks a "px" at the end of the numbers and assigns that to the left and top properties.

Moving in a Simple Path

To make a DIV move in a smooth line rather than a jump, you should use the same setTimeout() trick I showed in the section on resizing images and letters. Take a look at this demo that smoothly moves a DIV across the screen. As you'll see if you look at the source of this example, the moveDiv() function only moves the DIV a small amount, and then uses setTimeout() to call itself in a short while. This is the essence of animation: many small differences over time simulating smooth movement.

There's a little trick in the moveDiv() function which stops the DIV when it hits a certain point. By placing the setTimeout() call in an if block, you can keep the DIV from moving if it has already gone far enough.

    if (new_left < 400)
    {
      the_timeout = setTimeout('moveDiv();',10);
    }

Or you could have the DIV change direction when it hits a certain point or start over in the same place it began.

Moving in a More Complicated Path

The solution above works when you want your DIV to follow a relatively simple path. In smooth_move.html, the DIV simply moves in a straight line. But if you want your DIV to follow a more complicated path, say a circle, or a more irregular path, you'll need additional code. If you're mathematically inclined, you can use a mathematical formula to determine where your DIV should go at each step. The formula for a line, y=mx+b, is relatively easy to code into your JavaScript. The formula for a circle (y^2 + x^2 = 1) is harder. And, if your path doesn't conform to a known geometric object, coming up with a formula in the first place can be tough.

If you don't feel like cracking open your math texts, you can simply create an array of points that describe the path and have your DIV move from point to point. The more points in the array, the longer or smoother your path will be. The square dance example shows one way to make a DIV move in a square. If you look at the source, you'll see that there's an array containing the points. After all the points have been visited, the code starts back at the beginning of the array. Each element in the array is a string with two numbers separated by a colon, for example, "160:100". These numbers are left and top positions. I used the split function to separate each array element into the two positions.

   var the_points = next_point.split(":");

   var left = the_points[0];
   var top = the_points[1];

The split() function takes a string and splits it into an array based on a delimiter you supply. You don't have to create the array beforehand as split() takes care of that for you. So, in the lines above, the string "160:100" gets split into two parts and loaded into the_points. The first element in the_points, the_points[0], will be 160, and the second element, the_points[1], will be 100.

Here's the function that moves the DIV:

function moveDiv(array_position)
{
  // get the style sheet
  //
  var the_style = getStyleObject('myDiv');
  if (the_style)
  {
    // go to the next point in the array
    //
    array_position = array_position + 1;
    
    // if we've gone past the end of the array, start
    // at position 0
    //
    if (array_position >= the_coords.length) {
      array_position = 0;
    }
    
    // turn the point "120:100" into an array of two
    // elements: the left and the top
    //
    var next_point = the_coords[array_position];
    var the_points = next_point.split(":");
    var left = the_points[0];
    var top = the_points[1];

    // now set the left and top
    // properties appropriately
    //
    if (!document.layers) 
    {
      left = left + "px";
      top = top + "px";
    }
    the_style.left = left;
    the_style.top = top;

    // and call moveDiv() again, with the current array position
    //
    the_timeout = setTimeout('moveDiv(' + array_position + ')',100);
  }
}

The call for the moveDiv() function contains a number that represents where the animation should go next in its path; that is, which element in the array it needs to process next. The link that triggers the animation, starts at the first element of the array, element 0:

<a href="#" onClick="the_timeout=setTimeout('moveDiv(0);',100); return false;">start moving!</a>

The function first gets the stylesheet information for the DIV. Then it adds one to array_position so that it knows to grab the next set of coordinates from the array. If the new array_position is past the end of the path array, array_position is reset to 0.

Once it has the array_position, it grabs the coordinates from the array, uses split() to determine the individual properties, and then sets the top and left properties of the DIV.

Finally, it uses setTimeout() to call the function again. Notice that the last line looks a little weird:

the_timeout = setTimeout('moveDiv(' + array_position + ')',100);

You might think that this would work:

the_timeout = setTimeout('moveDiv(array_position)',100);

Unfortunately, the array_position variable only exists inside the moveDiv() function. Once the function exits, the variable disappears. In 100 milliseconds, when setTimeout() tries to call moveDiv() again, JavaScript will try to look up the value of array_position. By that time that iteration of the moveDiv() function will have ended and JavaScript won't know what that variable is, causing an error.

To overcome this annoyance, avoid passing variables into a function call of a setTimeout() and instead pass the values of the variables.

Pages: 1, 2, 3

Next Pagearrow