Here is a little HTML5 canvas experiment: a digital clock created from particles. The particles take the form of numerals which slide into place to display the correct current time. Click here or on the screenshot below to see it in action.

Download

Download the full commented source code here: ParticleClock.zip

About the Code

The code is fairly well commented, so I will keep my remarks to a minimum. Of interest is the method for finding the correct current time and parsing out the digits which form it. We create a new Date object, read its hours, seconds, and minutes, and do some computation to find separate tens and ones digits. (Note the code creates a twelve-hour clock, the type familiar to North Americans and others. This can be easily removed.) For later use in the code the time digits are stored in an array, digit:

date = new Date();
sec = date.getSeconds();
minute = date.getMinutes();
hour = date.getHours();

//comment out the next two lines to get a 24-hour clock
hour = hour % 12;
if (hour == 0) {hour = 12;}
///////////////////////////////////////////////////////

digit[5] = Math.floor(hour/10);
digit[4] = hour - 10*digit[5];

digit[3] = Math.floor(minute/10);
digit[2] = minute - 10*digit[3];

digit[1] = Math.floor(sec/10);
digit[0] = sec - 10*digit[1];

The particles

The particles in this example are stored as JavaScript objects similar to the particles in my earlier examples (see here and here). In the clock example, each particle keeps track of its position, velocity, and color. The particles are kept into a 2D array which sorts them based on what numeral they display. When a certain digit is needed for the next displayed time, it is chosen randomly from the available particles.

The motion

To keep things interesting, a little physics is applied to the particles. I experimented with dozens of versions of this clock, and you may have some fun trying out other particle behaviors. Here, when a digit is sliding into place to become part of the new displayed time, it repels other particles (within a certain distance) according to an inverse-square law, which is similar to the electromagnetic repelling force between two oppositely charged particles. Once the particle is in place as part of the displayed time, it no longer repels.

To keep the motion from becoming to wild, the velocity of the particles is continually damped by simply multiplying by a number smaller than one on every refresh of the screen. Also, the particles are kept inside the display area by bouncing them off the walls.

Tweening

As a particle moves into place to become part of the displayed time, its color changes, while the discarded particle changes back to its inactive color. These transitions, or tweens, of position and color values occur over several frames (display refreshes) and are controlled by a single parameter. To add some “easing” to the tween, we use a cosine function:

s = 0.5-0.5*Math.cos(digitCount[i]/framesPerMotion*Math.PI);

Here, digitCount[i] is a counter (one for each time display particle currently moving into place) which increments from 0 to framesPerMotion. The argument inside the cosine function ranges from 0 to pi, and the scaling and offsets used create a cosine function ranging from 0 to 1, with slower changes at the endpoints and more rapid change in the middle. This one parameter s is then used to control the transition of several things: the position of the particle sliding into place (x and y coordinates), the color of this particle (its red, green, blue, and alpha values), and the color of the discarded particle as it transitions back to the inactive color and alpha.

For example the particle stored as digitParticle[i], which is sliding into place to become part of the displayed time, has its alpha altered by the code:

digitParticle[i].a = minAlpha + (maxAlpha - minAlpha)*s;

When s is zero, the alpha will be minAlpha, and when s reaches 1, the alpha will be maxAlpha.

Optimizing

The code could certainly be optimized, and perhaps a future version will be able to display many more particles. Accessing the 2D particle array repeatedly may come at a cost, and linked lists could make this faster. See my previous posts for examples of using linked lists. Here, since the particles need to be sorted according to what numeral they display, a slightly more complex data structure would need to be used.

Another significant optimization would be to use a sprite sheet to store images of each of the numerals so that they don’t have to be individually redrawn each time using the fillText() method. I have chosen to draw them all individually for simplicity, but since the digits all look the same (when they are not part of the displayed time), drawing from a stored bitmap would likely be much faster.

Experiment!

The particles interact based on a repelling force, as described above. But you may find some other clever ways to make them behave. Add some collision detection along with billiard physics (but you’ll probably need to do some optimization first), or just change the constants which control the amount of repelling force. Perhaps the particles should all repel each other all the time, or they should behave differently depending on what digit they display. Have some fun and let me know if you come up with anything new!