[ Team LiB ] |
13.10 Animating Circular Element PathsNN 6, IE 5 13.10.1 ProblemYou want to animate the position of an element in a circular path. 13.10.2 SolutionTo 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:
A typical set of values to put an element into motion might be as follows: initCircAnime("rounder", 200, 200, 36, 10); 13.10.3 DiscussionThe 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 AlsoRecipe 13.9 for straight-line animation; Recipe 3.7 for creating a custom object. |
[ Team LiB ] |