Animation on canvas: Create a clock in HTML5

In this article I will see that how can you create a analog clock on canvas element and JavaScript in HTML5. This article also gives you a better understanding of how to draw arcs and lines on canvas in HTML5.

The below example uses canvas so your browser should support HTML5 canvas element otherwise you will need to update your browser to run the example.

Create an HTML file which contains canvas element. Like this:

<html>
<head>
    <title>Create Clock in HTML 5</title>
</head>
<body>
    <canvas id="MyCanvas" width="400" height="400"></canvas>
	</body>
</html>

The above code contains a canvas element with a width and height attribute. It is required to set width and height of the canvas because we will the value of these attribute to draw the arcs, hands and hours numbers within clock.

Now see the full code:

   <script>
        var canvas = document.getElementById('MyCanvas'),
            context = canvas.getContext('2d'),
 
            actualRadius = canvas.width / 2,
            fontSize = actualRadius / 10,
            clockMargin = actualRadius / 20,
            hoursPadding = actualRadius / 6,
 
            radius = canvas.width / 2 - clockMargin,
            handRadius = radius - hoursPadding,
 
            handPadding = actualRadius / 10, 
            hourHandPadding = actualRadius / 5,
            loop;
        context.font = fontSize + 'pt Calibri';
 
 
        function drawCircles() {
            context.beginPath();
            context.arc(canvas.width / 2, canvas.height / 2, radius, 0, Math.PI * 2, true);
            context.lineWidth = actualRadius / 13;
            context.strokeStyle = "#565655";
            context.stroke();
            context.closePath();
 
            context.beginPath();
            context.lineWidth = actualRadius / 20;
            context.arc(canvas.width / 2, canvas.height / 2, radius - context.lineWidth, 0, Math.PI * 2, true);
 
            context.strokeStyle = "#b5b5b5";
            context.stroke();
            context.closePath();
 
            context.restore();
            context.beginPath();
            context.arc(canvas.width / 2, canvas.height / 2, 5, 0, Math.PI * 2, true);
            context.fill();
        }
 
        function drawHours() {
            var angle = 0,
                hourWidth = 0;
            for (var hour = 1; hour <= 12; hour++) {
                angle = Math.PI / 6 * (hour - 3);
                hourWidth = context.measureText(hour).width;
                context.fillText(hour,
                    canvas.width / 2 + Math.cos(angle) * (handRadius) - hourWidth / 2,
                    canvas.height / 2 + Math.sin(angle) * (handRadius) + fontSize / 3);
            }
        }
 
        function drawHand(pos, isHour, lineWidth) {
            var tempHandRadius;
            var angle = (Math.PI * 2) * (pos / 60) - Math.PI / 2,
                tempHandRadius = isHour ? handRadius - hourHandPadding :
                handRadius - handPadding;
            context.lineCap = "round";
            context.moveTo(canvas.width / 2, canvas.height / 2);
            context.lineTo(canvas.width / 2 + Math.cos(angle) * tempHandRadius,
                (canvas.height / 2 + Math.sin(angle) * tempHandRadius));
            context.lineWidth = lineWidth;
            context.stroke();
        }
 
        function drawHands() {
            var date = new Date,
                hour = date.getHours();
            hour = hour > 12 ? hour - 12 : hour;
            drawHand(hour * 5 + (date.getMinutes() / 60) * 5, true, 8);
            drawHand(date.getMinutes(), false, 4);
            drawHand(date.getSeconds(), false, 1);
        }
 
        function drawClock() {
            context.clearRect(0, 0, canvas.width, canvas.height);
            context.save();
            context.fillStyle = 'rgba(255,255,255,0.8)';
            context.fillRect(0, 0, canvas.width, canvas.height);
            drawCircles();
            drawHands();
            context.restore();
            drawHours();
        }
 
        loop = setInterval(drawClock, 1000);
    </script>

Above, you can see the ‘drawClock()’ method which is calling at interval draws the clock on canvas. The interval is in milliseconds. The ‘drawClock()’ will be called in every 1000 milliseconds which is equal to 1 second.

The above code declares some global variables which contains the values in ratio of canvas width. The ‘actualRadius’ is the radius of the clock which is the half of the canvas width, ‘clockMargin’ is just the margin from the canvas boundary, ‘hoursPadding’ is the padding value with outer circles of the clock, ‘radius’ is the actual radius of the drawn clock and the ‘handRadius’ is the radius of hands of the clock. And

drawCircles() method

The ‘drawCircles()’ method draws border with two outer circle and one in the center which is the base of clock’s hands. We are using arc() method to draw the circles. The first outer circle has the context.strokeStyle = “#565655” and second has context.strokeStyle = “#b5b5b5” which gives the colors of the circles.

Draw borders of the clock in HTML 5
Draw borders of the clock in HTML 5

drawHours() method
The ‘drawHours()’ method draws the number of the hours just after the clock’s border.

drawHands() method

The ‘drawHands()’ method draws teh hands of the clock for showing current hour, minute and seconds. This methods uses two methods such as moveTo() and lineTo().
See here how do moveTo() and lineTo() methods work.