Bringing our CSS clock to life using JavaScript's requestAnimationFrame()
method

As JavaScript enthusiasts, most of us probably have at some point created
a
live time
display in JavaScript and watched with glee as it accessed the actual
time on our computer and showed it. Not to trivialize those accomplishments,
that process undoubtedly involved creating a new instance of
the Date() object and repeatedly looking up the value of the
various time fields inside a setTimeout or setInterval
method. Well, that same time tested process is still relevant for the most part when it comes to breathing life
into our modern CSS clock variant, except we'll be converting each time
field's value (ie: 13hr) into degrees, and for performance sake, ditch
setInterval for the more efficient requestAnimationFrame()
method.

Setting the clock hands using JavaScript/ jQuery

To set the clock hands in JavaScript, we first express each time field in
terms of degrees, then set the CSS3 property
transform:rotate(deg) on each hand to that degree to rotate
it. We'll turn to jQuery to do this, as it
automatically takes care of accessing the supported version of the
transform property in the user's browser, saving us from the drudgery of
dealing with those vendor prefixes ourselves.

To illustrate, lets create a JavaScript function that manually sets the
time on our CSS clock to anything you want, by converting each time unit (ie:
12hr) to degrees:

If you examine the function, you'll see how the conversion from
conventional time unit to degrees occurs. For the hour field, we divide the
hour (ie: 13hr) by 12 to first get it as a fraction of a full 12 hr cycle,
then multiple that by 360 to get the final value as a fraction of 360 deg.
The same principle goes behind the minute and second fields, except we
divide by 60 instead of 12.

Just for fun, the following uses the above function plus a form to let
you set the desired time on the CSS clock visually:

Demo:

hrs Please enter number between 0-23
mins Please enter number between 0-59
secs Please enter number between 0-59

The time has arrived...

With our good grasp now on the various components that make up our
CSS clock and how to get its hands to do our bidding, we're ready to
make the final plunge of bringing it to life. We'll add two refining
tweaks to the final clock to uphold our reputation as masters of our
trade! They are:

Modify the Math used so the hour and second fields are more
accurate than just to the nearest hour and second. Instead of just
returning whole integers, we'll make them return floating numbers
that take into account the current minute and millisecond,
respectively. When the clock is shown then, the two hands will
animate with finer incremental steps.

Ditch the old setInterval() method of JavaScript
for the less fallible requestAnimationFrame() method
of repeatedly calling a function to update our clock.
requestAnimationFrame() is much more predictable in how often
it updates itself compared to the former, minimizing frame skipping
and better adapting to available system resources. More on this
below.

Without further adieu then, here is our modest script that turns
Pinocchio into a real boy!

Right near the top of the code you see the reference to the method
requestAnimationFrame, which simply put executes the function passed into it
once just like with setTimeout(), except instead of after the user specified
delay, it does this automatically just before the next available screen
repaint, which based on a typical device's 60 frames per second screen
refresh rate would mean just before 16.7 milliseconds (1000/60) or so. In
other words, requestAnimationFrame lets us run any function automatically as
soon as the browser is able to repaint the screen, compared to setTimeout's
user defined delay. So far so good?

When requestAnimationFrame is called recursively, such as inside
the function we pass into it, it behaves a lot like setInterval,
except it repeats itself not based on the user defined interval, but once
again, at every next available screen repaint. That's what's happening in
the code above. So what's the point you're already asking. Well, when we're
running JavaScript code that paints to the screen (ie: in an animation),
when the browser is able to repaint the screen will differ greatly based on
system resources and frame refresh rate, and relying on setInterval()'s
interval parameter becomes meaningless, even inefficient if the browser
tries to execute your code before it's able to show it on the screen.
requestAnimationFrame takes care of this issue by repeating itself only when
the user's computer is ready for a screen repaint, and furthermore, pauses
the animation when the page isn't visible (which on mobile devices conserves battery). All together this leads to a much smoother, consistent
animation experience to the user.

requestAnimationFrame is supported in IE10+, FF4+, Chrome 10+, and Opera
15+. For browsers that don't recognize any variant of requestAnimationFrame in
the form of vendor prefixes, we fall back to the good old setTimeout method,
as illustrated in our code:

Inside the fallback setTimeout code, notice how we've set the delay value
to 1000/60, or roughly 60 invocations per second. As available system
resources rise or fall that delay value becomes meaningless, unlike with the
actual requestAnimationFrame method, but it's a noble attempt nonetheless.

Lets move on to the updateclock() function now. To make the
return values for the hour and second hands accurate to the minute and
milliseconds, respectively, we include the current minutes and milliseconds
when calculating the equivalent degrees for these two fields (see code in
orange). The result is clearly visible with the seconds hand as it moves in
an unabated manner around the clock.

Our adventures into CSS3 clock making ends here, but may it open up the
possibilities for you for creating even more elaborate crafts using CSS!