I'm Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with HTML, CSS and SVG. To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

my books

Pro CSS3 Animation book coverPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head CanonMassive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

The New DefaultsThe New Defaults — A Sass color keyword system for designers.

CSSslidyCSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

An SVG Analog Clock In 6 Lines of JavaScript

Compared to the JavaScript digital clock I demonstrated in the previous article, this SVG analog clock uses fewer lines of code, and has the advantage...

Compared to the JavaScript digital clock I demonstrated in the previous article, this SVG analog clock uses fewer lines of code, and has the advantage of being infinitely scalable.

I’ve always admired the elegance of the code, expressed earlier by Felix Gnass. First, there’s my version of the SVG, which consists of just four elements: the dial, and three rectangular hands (hours, minutes, and seconds):

<svg id="clock" viewBox="0 0 100 100">
  <circle id="face" cx="50" cy="50" r="45"/>
  <g id="hands">
    <rect id="hour" x="48.5" y="12.5" width="5" height="40" rx="2.5" ry="2.55" />
    <rect id="min" x="48" y="12.5" width="3" height="40" rx="2" ry="2"/>
    <line id="sec" x1="50" y1="50" x2="50" y2="16" />
  </g>
</svg>

The markup is, I hope, fairly self-explanatory: the <circle> element has a radius of 45 units, with its center 50 units from the top left corner of the SVG element; the hour, min and sec elements are positioned similarly. The hour and minute hands are rectangles 40 units long, and have a border-radius (in SVG, applied as rx and ry).

Rather than trying to style the elements inline, I’ll do that in CSS:

#face { stroke-width: 2px; stroke: #fff; }
#hour, #min, #sec { stroke-width: 1px; fill: #333; stroke: #555; }
#sec { stroke: #f55; }

At this point, the clock has all hands pointing to 12. The JavaScript, written at the bottom of the page, changes all that:

setInterval(function() {
function r(el, deg) {
el.setAttribute('transform', 'rotate('+ deg +' 50 50)')
}
var d = new Date()
r(sec, 6*d.getSeconds())
r(min, 6*d.getMinutes())
r(hour, 30*(d.getHours()%12) + d.getMinutes()/2)
}, 1000)

This differs from the previous script in several significant ways:

First, it uses a setInterval that encompasses the entire script. The function inside runs every second, due to the 1000 passed to setInterval as an argument in milliseconds.

d is a variable based on the Date() object, just like the previous example. For brevity, the script takes advantage of the fact that elements with an id attribute automatically become references in scripts. While this isn’t a recommended practice, it’s certainly doable, making the use of sec, min and hour in the script direct references to the matching SVG elements.

The r function takes two arguments: the element to change, and the amount of rotation. Note that we’re taking about SVG rotation, not CSS, so there’s no need for vendor prefixes.

For sec, r is passed the id of the element, and 6 × the number of seconds in the current time. If it’s 0 seconds, deg will be 0, meaning that the element won’t rotate at all. If it’s 30 seconds, 30 × 6 = 180° of rotation. (The 50 50 value ensures that the element always rotates from the center of the SVG). min takes gets the same treatment, while hour is a little tricker: it uses the remainder of dividing the current hour by 12, multiplied by 30, and adds the number of minutes divided by 2. In other words, if it is 15 minutes past midnight, the calculation becomes:

r(hour, 30 * 0 + (15 / 2))
> 7.5

It if it is 3.45pm (remembering that JavaScript uses 24 hour time by default, so the hour division will be 15 % 12. The calculation is:

r(hour, 30 * 3 + (45 / 2))
> 112.5

All told, it’s a very nice little piece of code, which I hope will find its uses in your projects. Inspect the code for this clock on CodePen

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.