Making an analog clock using the HTML5 canvas tag

It’s been a long while since I have posted anything, this keeps happening but ah well. Anyway, in this post I am going to show you how to create an analog clock using JavaScript and the HTML5 canvas tag.

The HTML

First let’s create a basic HTML5 page that will contain the canvas tag and other markup:

The JavaScript

As you can see I have made the page link to an external JavaScript file and call a set up method, these will be explained below. I’ve done this so that it is easy to include the HTML5 clock on any page with minimum hassle. The JavaScript code itself makes use of no external libraries like jQuery so it is portable.

Below you can see the contents of the JavaScript file:

This file consists entirely of the method setupAnalogClock(). I will now run through the file and how it works:

  • setupAnalogClock() takes 2 parameters; the first is the canvas element, the second is the width (diameter) of the clock.
  • Once called we begin by get the canvas context and getting the centre coordinates of the canvas.
  • After doing that I defined a method called tick() that will be run once a second and will update and process all the drawing of the clock.
    • Within tick() I defined two other functions called drawStatic(), and drawHand().
    • drawStatic() simply draws all the static parts of the clock, this includes the face, the centre point and the lines representing numbers around the face of the clock.
      • The lines representing numbers are drawn in their own function called drawNumbers() which counts backwards from 12 and draws each line in place.
    • drawHand() is a method that takes 2 parameters; the first being the length of the hand (this should be between 0 and the radius of the clock) and the angle at which to draw the hand.
    • The colour and line width of each hand is set before calling drawHand() in the tick() function.
  • At the end of setupAnalogClock() we call tick() once (to draw onto the screen) and then use┬ásetInterval() to call tick() once a second while we stay on this page.

The results look like this (for a live version click here):

Example of Analog Clock made using HTML5 Canvas

The canvas is slightly larger than the clock face to accommodate the line width of the face.

How the Hands Work

The hands (and the hour markings) work by using transforms supported by HTML5′s canvas tag and some basic mathematics.

Firstly I worked out a few equations based upon some facts:

  • There are 360 degrees in a circle (which in radians is 2 * pi).
  • There are 12 hours on a clock face.
  • There are 60 minutes in an hour.
  • There are 60 seconds in a minute.

From these you can work out the degrees a hand should rotate based upon what it is representing:

  • 360 / 12 = 30. Which is the number of degrees the hour hand should rotate per hour. e.g. at 9 o’clock the hour hand should of rotated 9 * 30 (270) degrees.
  • 360 / 60 = 6. Which is the number of degrees the minute hand should rotate per minute AND the number of degrees the second hand should rotate per second.

Of course the rotate methods for the canvas tag use radians instead of degrees (like most programming languages and libraries) so we then need to translate these degrees into radians by simply multiplying them by pi / 180.

So using these the method for drawing the hands becomes simple;

  1. First we translate to the centre of the watch.
  2. Then we rotate by the desired angle. (taking into account that the canvas origin is at the top left).
  3. Then we draw the line from where we are up to the desired length.

Hopefully this will help others to create a little HTML5 analog clock. Feel free to use the code, just don’t try to claim it as your own! I wrote this quickly while trying to make a nice replacement for the analog clock on iGoogle (since iGoogle will be disappearing soon) using HTML5, I will next try to create one that makes use of CSS3 transforms instead of the canvas tag.

You may have noticed the commented out code for numbering, I didn’t have it active because I couldn’t get them looking satisfactory and I think it looks better without them anyway.

Happy Coding!

14 Comments

  1. Thai says:

    I’d like to draw the hour number on the clock (i.e. all the numbers from 1 to 12). How could I do that?

  2. Sueli says:

    Thanks Lyndon! Loved the simplicity!

  3. This is exactly what I was looking for in a web project I am creating. Thanks a lot.

  4. J. Deltree says:

    Hi,

    How can one incorporate a timezone into this analog clock. This currently only seems to work with a user’s system time.

    Is there a way?

    Thanks.
    J.

  5. Petr Kozelka says:

    Hi Lyndon, thanks for sharing this nice and simple code. I would like to use slightly modified version of it in my company’s code, but cannot do it unless you specify license under which it is published.
    Would you mind adding it either to the article, or to the code comments?
    Thanks

    • Sorry for the very late reply! If you are still interested, feel free to use it how you like, but please add a comment with my name and a link to the blog post in your source file comments so anyone looking at it knows where it’s from (similar to the CC BY 4.0 license).

  6. The hour hand is not quite right. You need to add (minutes/60) * (360/HoursPerClock – or 2Pi/HoursPerClock )

  7. sunanda says:

    GREAT ! IT’S HELPFUL.

  8. Wayne Stewart says:

    Thanks for the help Lyndon been looking for a HTML5 based analogy clock for sometime now. Will make sure you get credit for it on my site.

  9. Thanks for this great code! I’ve used it and given you credit on my language blog for an interactive exercise about how to tell time in different languages. http://hugginsinternational.blogspot.mx/2014/05/time-machine.html

  10. As George Sexton pointed out, the hour hand was staying put at the exact hour position and not gradually moving in relation to the minute hand. I made the following correction based on the formula “Equation for the angle of the hour hand” (1/2(60*H+M) http://en.wikipedia.org/wiki/Clock_angle_problem

    So in the JS code I changed the order of the variables minutes first because the hours variable depended on the definition of the minutes and added another variable:
    var minutes = date.getMinutes();
    ctx.strokeStyle = “black”;
    ctx.lineWidth = 2;
    drawHand(clockWidth/2, minutes * 6);

    var hours = date.getHours();
    ctx.strokeStyle = “black”;
    ctx.lineWidth = 2;
    var hourdegree
    if(minutes==0){hourdegree=hours*30}
    else if(minutes>0){hourdegree=(((60*hours)+minutes)/2)}

    drawHand(clockWidth/3, hourdegree);

    I hope that helps anyone else who was having some difficulty with the hour hand.

  11. milen says:

    This can fix the problem with the origin of the text. For me worked fine
    ctx.textAlign = ‘center’;
    ctx.textBaseline = ‘middle’;

  12. kevin green says:

    hi, can anyone help me out with this. I want the clock hands to turn counter-clockwise, where do I make the changes?

    • Hi Kevin. The drawHand function takes the angle to draw the hand at as an argument, so what you can do is invert the angle you give to it, e.g. drawHand(clockWidth/3, -1*(hours * 30));

      If you’re new to the HTML5 canvas I’d recommend looking at this site: http://www.html5canvastutorials.com/

      It’s got a very good set of tutorials on the different features of the canvas element and how to use them.

Leave a Reply