March - HTML5 Canvas Clock Script

March is a Javascript script file which will draw and animate analogue clocks on HTML5 canvas elements. Getting away from my usual naming convention, I have called it "March" instead of "ClockCanvas" or "WatchCanvas" - there is no prize for figuring out why. As with TagCanvas and Glowspot, I'm releasing it under the LGPL v3 license. Here are two example clocks using the script:

Standard clock, no options set

Background image, no dial, image-based hands

The clock on the left is using the default options. The clock on the right uses a background image instead of a drawn dial, and the hands are drawn using PNG images. The right-hand clock should also be showing UTC (or GMT if you prefer) instead of your local time.

Note: the canvas element is not supported by Internet Explorer versions up to and including version 8. I have made no attempt to get March working with ExplorerCanvas, though some parts of it do. Image-based hands certainly will not work. IE9 supports canvas scripts without any problems.

Instructions

1. Download the javascript file from here: march.js version 1.0 (6.1k) or minified version (4.0k)

The minified version has been compressed using the Yahoo! YUI Compressor.

2. Include the file into your page:

<script src="march.js" type="text/javascript"></script>

3. Add a canvas to your page, with the required width and height:

 <canvas width="200" height="200" id="clockCanvas">
  <p>Browsers that do not support the canvas element will show this text. Probably.</p>
 </canvas>

4. Start the clock by passing the ID of your canvas to the startClock function:

 <script type="text/javascript">
  window.onload = function() {
    try {
      startClock('clockCanvas');
    } catch(e) {
      // in Internet Explorer there is no canvas!
      document.getElementById('myCanvasContainer').style.display = 'none';
    }
  };
 </script>

The startClock function takes an optional second argument for configuring how the clock should appear:

   ...
   startClock('clockCanvas',{
     tick: true,
     tz:   8
   });
   ...

The options available for configuring the clock are listed below.

Functions

There are only two functions exported by the March script:

startClock(id [,options])

Starts a clock on the canvas with the specified ID. The function may be called again with different options to change the appearance of a clock after it has been started.

stopClock(id)

This function will stop the clock with the specified ID. The redraw loop is stopped, and the hands remain in their current position without being redrawn. The clock may be restarted with the startClock function.

Options

There are a number of options for configuring how the clock appears. This first table lists the options that affect the behaviour of the clock as a whole. The default values are shown in the second column of each table below.

Clock options - Hide table

OptionDefaultDescription
x null X-coordinate of clock centre (null = centre within canvas)
y null Y-coordinate of clock centre (null = centre within canvas)
width null Width of clock in pixels (null = fit to canvas)
height null Height of clock in pixels (null = fit to canvas)
noFace false If true, the dial marking are not drawn
diameter 50 Clock diameter
tick false If true, the second hand will tick, otherwise it will sweep
useRAF false If true, mozRequestAnimationFrame or webkitRequestAnimationFrame will be used when available
interval 50 Time inverval between frames in milliseconds when not using moz- or webkit- RequestAnimationFrame
offset null Offset time by this many seconds
tz null Offset in hours from UTC (null for no offset, 0 for UTC)
startTime null Time to start clock with, in seconds past 12:00:00
Clock options

Unless the width or height options are set, the size of the clock is determined by the size of the canvas. Changing the x and y options will only change the position of the clock and will not affect its size.

Setting either the width or height option will scale the clock to fit within the specified area. Setting both options for the same clock will distort the shape of the clock to fit both width and height - including the hands!

The offset, tz and startTime options provide some control over the time displayed. The tz sets the clock to the time in the specified time zone, in hours before or after UTC.

The startTime option starts the clock at a specific time, defined in seconds from midnight/midday (it is only a 12-hour clock). As an example, to start the clock at 2:15, startTime should be set to (2 × 3600) + (15 × 60) seconds. 3600 is the number of seconds in an hour, in case that is not obvious.

The offset option adds or subtracts the number of seconds specified from the time. It may be used together with the tz or startTime options, or by itself to offset the standard browser time.

Dial options

The dial options specify how the markings around the clock are drawn. All measurements are relative to the diameter option.

Dial options - Hide table

OptionDefaultDescription
dRadius 22 Dial radius
dFill null Dial fill colour, null for not filled
dThickness 1 Dial marking thickness
dColour #999 Dial colour
dCap butt Dial marking end cap style
dHourR1 16 Hour marking inner radius
dHourR2 22 Hour marking outer radius
dHThickness dThickness Hour marking thickness
dHColour dColour Hour marking colour
dHCap dCap Hour marking end cap style
dMinuteR1 20 Minute marking inner radius
dMinuteR2 22 Minute marking outer radius
dMThickness dThickness Minute marking thickness
dMColour dColour Minute marking colour
dMCap dCap Minute marking end cap style
Dial options

Several of the options in this list and the list of hand options below specify an "end cap style". This diagram shows the three styles of line end cap:

End cap diagram

The three styles are: A - butt; B - round; C - square. The difference between the butt and square endings is that the butt cap style stops at the end of the line and the square cap protrudes past the end of the line by 1/2 the line width.

Hand options

The options in this next table define how the hour, minute and second hands are drawn. The diagram below shows which parts of the hand each of the different options refer to. All these measurements are relative to the diameter option.

Hand diagram

A = length, B = overlap, C = thickness, D = blob

Hand options - Hide table

OptionDefaultDescription
sLength 20 Length of second hand
sOverlap 5 Second hand overlap
sColour red Second hand colour
sCap butt Second hand end cap style
sThickness 0.75 Second hand thickness
sBlob 1.5 Second hand blob radius
sImage null Path to image for second hand
mLength 18 Length of minute hand
mOverlap 1 Minute hand overlap
mColour #000 Minute hand colour
mCap butt Minute hand end cap style
mThickness 1.25 Minute hand thickness
mBlob null Minute hand blob radius
mImage null Path to image for minute hand
hLength 12 Length of hour hand
hOverlap 1 Hour hand overlap
hColour #000 Hour hand colour
hCap butt Hour hand end cap style
hThickness 1.5 Hour hand thickness
hBlob 1.5 Hour hand blob radius
hImage null Path to image for hour hand
Hand options

The image-based hand options hImage, mImage and sImage should be given paths relative to the page that the clock will appear on. The hand images should be pointing straight up to 12:00. The length and overlap options can be used to scale and position the hands within the dial.

The code example below shows how the right-hand clock at the top of the page is configured.

<style type="text/css">
#clock2 {
  background-image: url(images/big-ben.png);
  border-color:     #c93;
}
</style>
<script type="text/javascript">
var bbopts = {
  noFace:      true,
  hideSeconds: true,
  mImage:      'images/big-ben-svg-minute.png',
  mLength:     24.5,
  mOverlap:    6,
  hImage:      'images/big-ben-svg-hour.png',
  hLength:     12,
  hOverlap:    5,
  tz:          0
};
window.onload = function() {
  startClock('clock2',bbopts);
};
</script>

History

Version 1.0
Initial release.

Help!

This script doesn't come with any guarantees. But if you do get stuck, or if you find any bugs, or if you have suggestions for improvements, please contact me at the usual address, graham(at)goat1000.com.