[ Team LiB ] Previous Section Next Section

13.10 Animating Circular Element Paths

NN 6, IE 5

13.10.1 Problem

You want to animate the position of an element in a circular path.

13.10.2 Solution

To animate a positioned element along a circular path, link the animeCirc.js library (Example 13-3 in the Discussion) to your page and invoke the initCircAnime( ) function with five parameters in the following sequence:

  1. ID of animated element (as string)

  2. x coordinate of start/end point of circle

  3. y coordinate of start/end point of circle

  4. Even integer value specifying the number of render points in the circle

  5. Integer value of relative radius of the circle

A typical set of values to put an element into motion might be as follows:

initCircAnime("rounder", 200, 200, 36, 10);

13.10.3 Discussion

The process for circular animation is similar to the straight-line animation of Recipe 13.9, but trigonometry assists in prescribing the path for the element. Example 13-3 shows the animeCirc.js library containing the code that performs the animation.

Example 13-3. The animeCirc.js library for circular animation
// animation object holds numerous properties related to motion
var anime = new Object( );
   
// initialize default anime object
function initAnime( ) {
    anime = {elemID:"", 
             xStart:0, 
             yStart:0, 
             xCurr:0, 
             yCurr:0, 
             next:1,
             pts:1,
             radius:1,
             interval:null
            };
}
   
// stuff animation object with necessary explicit and calculated values
function initCircAnime(elemID, startX, startY, pts, radius) {
    initAnime( ); 
    anime.elemID = elemID;
    anime.xCurr = anime.xStart = startX;
    anime.yCurr = anime.yStart = startY;
    anime.pts = pts;
    anime.radius = radius;
    // set element's start position
    document.getElementById(elemID).style.left = startX + "px";
    document.getElementById(elemID).style.top = startY + "px";
    // start the repeated invocation of the animation
    anime.interval = setInterval("doCircAnimation( )", 10);
}
   
function doCircAnimation( ) {
    if (anime.next < anime.pts) {
        var x = anime.xCurr + 
           Math.round(Math.cos(anime.next * (Math.PI/(anime.pts/2))) * anime.radius);
        var y = anime.yCurr + 
           Math.round(Math.sin(anime.next * (Math.PI/(anime.pts/2))) * anime.radius);
        document.getElementById(anime.elemID). style.left = x + "px";
        document.getElementById(anime.elemID). style.top = y + "px";
        anime.xCurr = x;
        anime.yCurr = y;
        anime.next++;
    } else {
        document.getElementById(anime.elemID).style.left = anime.xStart + "px";
        document.getElementById(anime.elemID).style.top = anime.yStart + "px";
        clearInterval(anime.interval);
    }
}

The library begins by defining an abstract animation object that gets initialized each time a circular path runs. Your scripts invoke the initCircAnime( ) function, which assigns parameter values to the anime object's properties. The function that executes repeatedly in response to setInterval( ) comes at the library's end.

The smoothness of the circular motion is controlled by the number of points along the circle at which the display should be updated. This value becomes the upper limit of anime.next in the if clause of doCircAnimation( ). To accomplish a full circle, the value by which Math.PI is divided in the next two lines must be one-half the maximum value in the condition. For any given combination of values, the radius of the circle is controlled by the multiplier at the end of the two statements containing Math.PI. The value (preserved as anime.radius) is not a straight pixel measure, but rather a factor that governs the radius. The larger the number, the larger the radius.

If you assign larger values for anime.pts (such as 72), the animation is smoother because the arcs between refresh points are much smaller. This also means that the motion is slower because the interval time (at 10 milliseconds) is essentially whirling as quickly as it can. On the other hand, too few refresh points, while faster, may appear too jerky for your users.

13.10.4 See Also

Recipe 13.9 for straight-line animation; Recipe 3.7 for creating a custom object.

    [ Team LiB ] Previous Section Next Section