Richard Gnall

Bouncing Ball DHTML Animation


Anyone who has tried animating web elements with DHTML has surely been disappointed by the slow speed by which these effects can be run.

This demo was originally created as a way of experimenting with a technique to speed up DHTML animations. Depending on the browser, clicking the above RUN ANIMATION button will open one or two instances of a bouncing ball animations. If only one animation opens up, click RUN ANIMATION again to open a second animation.

Note that the animations run faster if multiple animations are running concurrently. This may not be the case with all browsers or operating systems.

Experiment with starting and stopping multiple animations.

Experiment with clicking "Start" multiple times in one of the animations.

Although this demonstration runs two identical copies of the same animation sequence, the two animations don't have to be identical. If two different animations are running concurrently, they will both experience the same increase in speed as two similar animations.

Instead of running multiple simultaneous animations, one can achieve faster animations by making repeated calls to the control loop. However with this technique, it may not be possible to stop the animation. In the demo, the STOP button is unable to track multiple calls to the control loop and fails to completely stop the animation. With some browsers, refreshing the window and then clicking STOP will stop the animation. (With some clever programming, it may be possible to track the number of times START has been clicked and stop all instances of the loop with just one click of the STOP button.)

Another way to speed up the animation is to change the number of pixels by which the animation moves in each step. In this example, the animation moves one pixel at a time. Increasing the number of pixels per step does increase the apparent speed, but at the expense of making the motion look jerky. The effect is similar to pressing START multiple consecutive times.

So, what's going on here?

Animating an object is done by using either setTimeout() or setInterval() JavaScript methods to set up a loop which continually repositions a layer. Although it is possible to specify a delay of 1ms with either of these methods, the reality is quite different.

In an article dating from January 2000, Smooth animation using DHTML, Morten Wang did extensive testing and found that it is not possible to move a layer faster than once every 53.3 ms in a Windows environment. Although this may sound fast, it is equivalent to only 18.8 frames per second, which is too slow. For smooth animation, one would like to achieve a rate of at least 25 frames per second, or a refresh interval of less than 40ms.

My dual animation demonstrates the effect of multithreading. By running two instances of the animation (or multiple calls to the same animation), I am spawning two sequences of calls to the same timer, which effectively boosts the looping rate. This technique is covered in depth in an article titled Speeding Up Frame Rates For DHTML Animation in Win98 by Mark Szlazak.

Just for fun

It's possible to resize the animation windows while the animation is still running. If you increase the size of a window, the animation automatically senses the change and the roving circle will explore the new territory.

If you resize the window to either a narrow vertical or horizontal strip, it's motion can be restricted to one dimension.

If you shrink the size of the window so that it totally obscures the circle, the circle will remain locked (hidden) in place until you re-adjust the size of the window to re-expose the circle.


In case you are unable to catch all of the text revealed by the roving "spotlight", it reads:

All the world's a stage,
And all the men and women merely players;
They have their exits and their entrances,
And one man in his time plays many parts, ...
– "As You Like It"
by William Shakespeare

To see the text as it is displayed in the animation window, select all of the text by clicking in the window and pressing <CTRL> A.