HTML clocks using JavaScript and CSS rotation

Warning: This isn't going to work in any currently available version of Internet Explorer* or many older browsers. The two clocks below are just HTML. There are no Adobe Flash files or my beloved <canvas> going on, just regular <div> and <img> tags. The way it works is by taking those images in an { overflow: hidden } <div> and rotating them, via JavaScript, using the proposed CSS transform property.







Background

In July last year, the excellent Jonathan Snook wrote an article about CSS rotation. If you're interested stuff like this and you haven't heard of Mr. Snook before, I suggest you read his stuff. He explains in his article that the Webkit (Google Chrome & Safari) and Firefox 3.5+ browsers support the CSS transform property. Since then, Opera has joined the party too. He also notes that it is also possible to implement basic (0° / 90° / 180° / 270°) rotations using Internet Explorer, but clearly this wasn't going to cut it for what I wanted to do here. The code to make the clocks work is really very simple. To do the rotation, simply use the following CSS declarations:





transform: rotate(42deg); // this won't work yet, but one day it may -moz-transform: rotate(42deg); // mozilla specific -o-transform: rotate(42deg); // opera specific -webkit-transform: rotate(42deg); // webkit specific

In jQuery that could look like:

$("#myElement").css({ 'transform': 'rotate(42deg)', '-moz-transform': 'rotate(42deg)', '-o-transform': 'rotate(42deg)', '-webkit-transform': 'rotate(42deg)' });

How it works

I don't really see the need to breakdown the code of the clocks themselves as JavaScript clocks have been around since, well, forever. However, I will quickly explain how it works should you want to inspect the code further. Originally, my code had one setInterval() timer that simply performed the required rotation(s) each second. Whilst it proved the concept was doable, it's jerkiness lacked the final effect I was after. To create a smoother animation, there are now two setInterval() timers. The first one runs once every second and updates the current time. It decides if each element (i.e. hours, minutes, seconds) is rotated to the correct angle and, if not, calculates the number of small steps it needs to take to get there. It pushes the value of these steps into an array. For example, let's say one of my images is currently rotated 12° but it should be turned to 18°. This step pushes the numbers 13, 14, 15, 16, 17 and 18 into that element's array. These are the small, incremental animation steps which, when animated, will look nicer than an abrupt jump from 12° to 18°. The second setInterval() timer runs must faster and is responsible for actually rotating the images. Each time it is run, it looks at each element and it if it's array is not empty it: takes the first value from that array (in our example, array[0] = 13) and rotates that image to 13° accordingly, and uses array.slice() to remove the first item from the array (in our example, the number 13). The next time this is run, array[0] now equals 14, and the image is rotated again. This process goes on until the array is empty. Each second the array is repopulated again by the first timer and the animation process starts again.









A couple of things to note