Analog Clock

The first code I'd like to show is this analog clock. It is embedded into a HTML5 <canvas> element and brought to life by JavaScript. During initialization, the size and color of the clock can be set up. Usually, the background is transparent and CSS can set the background-color.

With the right browser (HTML5) and support for iframes, you should see the analog clock below this text. If iframes are causing trouble, you can also try the direct link at /stuff/clock/clock.html.

Here is the underlying HTML5 code:

<!DOCTYPE HTML>
<html>
<head>
<title>Clock Animation</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="clock.js"></script>
<style type="text/css">
canvas {
	background-color: #000;
}
</style>
</head>
<body onload="initClock('clock', 100, 'rgb(255, 255, 255)')">
  <canvas id="clock"></canvas>
</body>
</html>

The needed JavaScript source, with its initialization method comes next. Via "initClock(<id_of_canvas_element>, <clock_size>, <color>)", the clock can be customized, the default values would be a black color, 100x100 pixel size and the canvas id set to 'clock'.

/**
 * Draws a clock into a canvas.
 * 
 * @author Joern Bernhardt
 */

// default values
var clock_id = 'clock';
var clock_size = 100;
var clock_color = 'rgb(0, 0, 0)';
setInterval(drawClock, 250);

/**
 * Initializes the clock canvas.
 * 
 * @param id
 *            The ID of the clock canvas element
 * @param size
 *            The size of the clock (size == width == height)
 * @param color
 *            The color of the clock in 'rgb(r, g, b)' format
 */
function initClock(id, size, color) {
	clock_id = id;
	clock_size = size;
	clock_color = color;
}

/**
 * Draws the clock.
 */
function drawClock() {
	var canvas = document.getElementById(clock_id);
	var ctx = canvas.getContext('2d');
	canvas.width = clock_size;
	canvas.height = clock_size;

	ctx.translate(clock_size / 2, clock_size / 2);
	ctx.fillStyle = clock_color;

	ctx.save();
	for ( var i = 1; i <= 60; i++) {
		ctx.rotate((Math.PI * 2) / 60);
		ctx.fillRect(-(clock_size / 2), 0, (i % 5 == 0) ? (clock_size / 20) : (clock_size / 35), 1);
		if (i % 5 == 0) {
			var text = i / 60 * 12;
			var metrics = ctx.measureText(text);
			ctx.fillText(text, -(metrics.width / 2), -(clock_size / 2) + (clock_size / 20) + 12);
		}
	}
	ctx.restore();

	drawTime(ctx);
}

/**
 * Draws the time itself.
 * 
 * @param ctx
 *            The 2d context of the canvas element
 */
function drawTime(ctx) {
	var now = new Date();
	var hrs = now.getHours();
	var min = now.getMinutes();
	var sec = now.getSeconds();

	// Seconds
	ctx.save();
	ctx.rotate(sec / 60 * (Math.PI * 2));
	ctx.fillRect(-1, 0, 1, -(clock_size / 2) / 1.5);
	ctx.restore();

	// Minutes
	ctx.save();
	ctx.rotate(min / 60 * (Math.PI * 2));
	ctx.fillRect(-1, 0, 1, -(clock_size / 2) / 2);
	ctx.restore();

	// Hours
	ctx.save();
	ctx.rotate((hrs % 12) / 12 * (Math.PI * 2));
	ctx.fillRect(-1, 0, 1, -(clock_size / 2) / 3);
	ctx.restore();
}

Have fun with it!

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd><h2> <h3> <h4> <h5> <h6>
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or class="OPTIONS" [title="the title"].
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.