Safari, Dashboard, and WebKit-based applications support the JavaScript canvas object. The canvas allows you to easily draw arbitrary content within your HTML content.
Introduction to the Canvas
Defining the Canvas
Drawing on a Canvas
A canvas is an HTML tag that defines a custom drawing region within your web content. You can then access the canvas as a JavaScript object and draw upon it using features similar to Mac OS X’s Quartz drawing system. The World Clock Dashboard widget (available on all Apple machines running Mac OS X version 10.4 or later) shows a good example , though using a canvas is by no means exclusive to Dashboard.
There are two steps to using a canvas in your web page: defining a content area, and drawing to the canvas object in the script section of your HTML.
To use a canvas in your web page you first set up the drawing region. The World Clock Dashboard widget designates this region with the following code:
<canvas id="myCanvas" width='172' height='172'/> |
In this context, the attributes of <canvas>
worth noting are id
, width
, and height
.
The id
attribute is a custom identifier used to target a particular canvas object when drawing. The width
and height
attributes specify the size of the canvas region.
Within the World Clock widget, this area is defined to be the canvas:
Now that the canvas region has been defined, it is ready to be filled.
Once you have defined the canvas area, you can write code to draw your content. Before you can do this, you need to obtain the canvas and its drawing context. The context handles the actual rendering of your content. The World Clock widget does this in its drawHands()
function:
function drawHands (hoursAngle, minutesAngle, secondsAngle) |
{ |
var canvas = document.getElementById("myCanvas"); |
var context = canvas.getContext("2d"); |
This function draws the hour, minute, and second hands on the face of the World Clock. As parameters, it takes the angles at which the three hands should be rotated as passed in by its caller.
You first query the JavaScript environment for the previously defined canvas, using its unique identifier: the id
attribute in the <canvas>
tag.
Once your script has acquired the canvas, you need to obtain its context. Using the getContext("2d")
method, assign the canvas’ draw context it to the context
variable. From this point on, you call all operations intended for the canvas on context
.
The first operation you perform empties the canvas. As the drawHands()
function is called every second, it is important to empty it each time, so that the previously drawn configuration doesn’t simply draw on top of the new configuration. The entire region, as defined by standard coordinates in the <canvas>
tag, is cleared:
context.clearRect(0, 0, 172, 172); |
Next, you save the state of the original context space so that you can restore later. In the original context, the origin (the 0,0 coordinate) of the canvas is in the top left corner. Upon completion of the upcoming drawing code, you want to return to this context. Use the context’s save method to do so:
context.save(); |
Since you want the hands of the clock to rotate around the center of the clock, translate the origin of the context space to the center of the canvas:
context.translate(172/2, 172/2); |
Then draw the hour hand on the face of the clock. You copy the current context (with the origin at the center of the clock face), so that it can restored later. Then, you rotate the entire context, so that the y-axis aligns itself with the angle that the hour hand should point towards. Next, you draw the hour hand image (created in the code as a JavaScript Image
object). The method drawImage()
has five parameters: the image to be drawn, the x and y coordinate for the bottom left hand corner of the image, and the width and height of the image. Remember that while you draw the image as going straight up within the graphics context, you rotated the context to be at the correct angle for the hour hand:
context.save(); |
context.rotate(hoursAngle); |
context.drawImage(hourhand, -4, -28, 9, 25); |
context.restore(); |
Once you draw the hand, you restore the last saved context. This means that the context that you saved four lines prior, with its origin at the center of the canvas but not yet rotated, will be the active context again.
Use a similar procedure to draw the minute hand on the face of the clock. The differences this time are in the angle you rotate the context to and the size of the minute hand. Note that you save and rotate the context again, and then you restore it to its previous state, so that you can draw the next element independent of the rotation needed for the minute hand:
context.save(); |
context.rotate (minutesAngle); |
context.drawImage (minhand, -8, -44, 18, 53); |
context.restore(); |
Finally, draw the second hand. Note that this time, the context should not be saved and restored. Since this is the last time anything will be drawn in this particular context (with the origin at the center of the canvas), it is not necessary for you to save and restore again:
context.rotate (secondsAngle); |
context.drawImage (sechand, -4, -52, 8, 57); |
context.restore(); |
} |
Now that the clock face has been drawn, you should restore the context to its original state, as saved before any drawing occurred. This prepares the canvas for any future drawing that will occur, and gives you a consistent origin (the top-left corner of the canvas) to work from.
Remember, all of these techniques can be applied to a canvas object within any WebKit-based application. For more information on the canvas see Canvas
.
© 2004, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-10-15)