### ClockSelector.js

4 November 2014

There are a lot of instructions for making a real-time clock using HTML 5's <canvas> element. None were sufficient for my purposes.

The TEAM SHABKYLE site has always had a dynamic background image: depending on your current clock time, the site shows a particular wallpaper, determined by which photograph was taken closest (temporally) to the time where you are. This is neat — if pointless — but it's not particularly noticeable unless you load the page regularly and at random intervals over a few days.

I wanted a clock object that would:

• Show the wall time, to imply that the background somehow varies intelligently
• Be user-manipulable, with feedback
• Drop into the page without too much hassle

Enter ClockSelector.js.

Adding this clock is as simple as including ClockSelector.js, then

new ClockSelector( 'clock0' ); // the id of the div above is clock0


It's that simple. You don't need a canvas element (although it will work with one); you don't need to write anything yourself. All you need is a div with width and height specified. For example:

Because why not drop three clocks in one page? The code for this (effectively) is:

<div id="clockN" style="width:NNpx;height:NNpx;"></div>
<script language="javascript">
new ClockSelector( 'clockN' );
</script>


That's all good and well. But what about customization?

Recoloring things is simple (see if you can figure out what highlight is affecting):

new ClockSelector( 'clock4', {
background:   '#536895',
color_border: 'white',
color_hour:   '#ffb300',
color_minute: '#229966'
highlight:    '#8c1515'
} );


Like the original colors but want to make the clock daintier?

new ClockSelector( 'clock5', {
stroke_border: 3,
stroke_minute: 1,
stroke_hour:   2,
scale_minute:  0.75,
scale_hour:    0.5
} );


Great. But what about real customization? (click it, I dare you)

new ClockSelector( 'clock6', {
callback: function ( c ) {
var t = c.clockTime();
var m = t.getMinutes();
m     = ( m < 10 ? '0' : '' ) + m;
document.getElementById( 'clock6digital' ).innerHTML = t.getHours() + ':' + m;
},
draw_second: function ( x ) {
x.arc( 0, 0, 80, 0, 2 * Math.PI );
x.fillStyle = 'yellow';
x.fill();
x.beginPath();
x.arc( 0, 0, 50, 1.2 * Math.PI, 1.8 * Math.PI );
x.strokeStyle = 'black';
x.lineWidth = 20;
x.stroke();
x.closePath();
x.fillStyle = 'black';
x.beginPath();
x.arc( 35, 35, 15, 0, 2 * Math.PI );
x.fill();
x.closePath();
x.beginPath();
x.arc( -35, 35, 15, 0, 2 * Math.PI );
x.fill();
x.closePath();
},
auto_dt: 100
} );


The thing is pretty general; you get the idea.

The simplest use case is new ClockSelector( 'div-id' ). This will automatically insert a user-manipulable analog clock sized to fit the div you specify.

When called new ClockSelector( 'div-id', params ), the clock can be customized with params — an associative array — with the following features:

• auto_dt: how often to automatically update the time on the clock, in milliseconds; default is 1000 (1 second)
• automate: whether or not to automatically update the time on the clock; default is true
• background: the background color of the canvas; default is 'black'
• callback: a callback function executed when the time on the clock changes, whether due to user manipulation or to automatic updating; takes a single argument, the ClockSelector object; an example is function ( clockselector ) { clockselector.clockTime(); }; by default this function is null
• color_border: the color of the clock border; default is '#fff'
• color_hour: the color of the hour hand; default is '#fff'
• color_minute: the color of the minute hand; default is '#aaa'
• draw_hour: a function to draw the hour hand; if null, draws a standard hour hand according to other parameters; function takes a single argument, a canvas context — see the clock6 example above; drawing area is -100 to 100 (x), and -100 to 100 (y), where positive y is up; the drawing is rescaled to the clock size; default is null
• draw_minute: see draw_hour
• draw_second: see draw_second; if null, does not draw a second hand
• highlight: highlight color when cursor is near the minute hand; default is '#f93'
• manual: whether or not to allow user manipulation; note that once the user has manually selected a time, any auto incrementing is halted; this can be reinitiated by calling clockselector.reset(); default is true
• scale_border: the radius of the clock border, specified as a fraction; default is 0.8
• scale_hour: the length of the hour hand, specified as a fraction; default is 0.4
• scale_minute: the length of the minute hand, specified as a fraction; default is 0.65
• stroke_border: line with of the clock border, scaled to assume that the clock is 100 pixels wide; default is 5
• stroke_hour: see stroke_border; default is 5
• stroke_minute: see stroke_border; default is 4

Reading through this, I see that it might be better to not mix measurement systems (fractions, per-100, per-200). As this is in the wild now, for the sake of backwards compatibility I will leave this as a future lesson.

Use as you will. Credit is desired but not necessary. Happy clocking.

Included $$\LaTeX$$ graphics are generated at LaTeX to png or by .