An Introduction to HTML5 Canvas

One of the great new elements in HTML5 is the Canvas elements. This is an element that takes everything that was about web display and exponents it. It has opened up the opportunity for JavaScript graphics APIs like C3DL to be made and used in much the same way the DirectX and OpenGL APIs exist for their desktop counterparts. It allows for the dynamic modification of video or other elements on the page at a pixel-by-pixel level as seen by Processing.js. With clever use, it can even be used to enhance video experience as seen by Popcorn.js and the upcoming effects extension Candy.js. All of this though, is above my head right now. Right now things are simple: Hello World on Canvas.

To use canvas effectively, you need to draw to it. To draw to it, you need to get the context you with to draw with. In most cases right now it will be 2D drawings (through which 3D can be simulated) but soon the webgl context will be standard implementation as well and will be possible to render true 3D images (C3DL uses webgl context). But I digress: back to Hello World on Canvas.

First, you have to get the drawing context from the canvas element (if available):

var canvas = document.getElementById("canvas");
if (canvas.getContext) { // Canvas Support
var ctx = canvas.getContext("2d");
// Work with context
}

This will give you everything you need to get ready to draw! Like all computer graphics, canvases work on a Cartesian Coordinate System, using x and y to specify points. Lines are drawn between 2 points like so:

ctx.beginPath(); // Tell the context you are drawing a path instead of a shape
ctx.moveTo(135,120); // Set the starting point (Point A)
ctx.lineTo(135,70); // Establish a line between Point A and this point (Point B)
ctx.stroke(); // Draw the line

Pretty easy to draw a line. Chaining lines together is possible too, just add more calls to ctx.lineTo() before drawing the line. If you want to make a closed shape made up of lines, that too is easy. Rather that drawing the last line to close a figure, there is a handy function to automatically connect a line from the last line drawn to where you started drawing. See the below code to draw a triangle:

ctx.beginPath(); // Tell the context you are drawing a path instead of a shape
ctx.moveTo(135,120); // Set the starting point (Point A)
ctx.lineTo(135,70); // Establish a line between Point A and this point (Point B)
ctx.lineTo(185,70); // Establish a line between Point B and this point (Point C)
ctx.closePath(); // Connect Point C to Point A
ctx.stroke(); // Draw the lines

Canvas also supports the drawing of things more complex than straight lines. An arc can be drawn by specifying a radius, the degree at which to start drawing (0 degrees, 90 degrees), the number of radians to draw and whether to draw clockwise or not. The below code draws a complete circle (0 to Math.PI*2 radians, or 0 to 360 degrees) with a radius of 25 pixels located at point 100,95. The circle is drawn clockwise (last parameter is true).

ctx.beginPath();
ctx.arc(100,95,25,0,Math.PI*2,true);
ctx.stroke();

Curves can also be drawn in both the quadratic and cubic (bezier) varieties. These curves are similar to normal arcs, but have one or two control points respectively to skew the curve. The following code draws a quadratic curve from Point A (135,120) to Point B (135, 95) with a control point at 180, 82.5:

ctx.beginPath();
ctx.moveTo(135,120);
ctx.quadraticCurveTo(180,82.5,135,95);
ctx.lineTo(150,120);
ctx.stroke();

A bezier curve is drawn similarly (use bezierCurveTo rather than quadraticCurveTo) with a secondary control point being specified just after the first control point. Up to now all this has been line-based drawings. But shouldn’t there be an easier way to draw a rectangle than by drawing 4 lines? There is!

ctx.strokeRect(60, 10, 10, 50);

This one line will draw a rectangle with the top-left corner at point (60,10) and give the rectangle a width of 10 and a height of 50. As this is not a point-to-point drawing this will be drawn without need to specify beginPath(), moveTo() or stroke() like in the earlier examples. But what if you wanted to fill in the enclosed area? Simple: rather than call strokeRect(), call fillRect() and the interior area will be filled! The same can be applied to filling line drawings by substituting the call to stroke() with fill().

Now that we have some lines and shapes on the canvas, we need to give them colour. Computer graphics quantify a colour by specifying the amount of red, green and blue in the colour on a scale of 0 to 255. Optionally, a fourth value, alpha, can be used to specify the transparency of the colour (0 is transparent, 1 is opaque, anywhere in between is translucent). This is done on the canvas by setting one of two properties: strokeStyle or fillStyle. Stroking also allows for another property, lineWidth, to be given to modify the weight of the line. These must be specified before drawing to have any effect:

// Stroke a semi-transparent red arc
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.lineWidth = 7;
ctx.beginPath();
ctx.arc(100,95,25,0,Math.PI*2,true);
ctx.stroke();

// Fill an opaque rectangle (no alpha specified means 100% opaque)
ctx.fillStyle = "rgb(255,0,0)";
ctx.fillRect(10, 10, 10, 50);

Note that the alpha doesn’t have to be specified, and that when you don’t you only say “rgb” instead of “rgba”. While these shape and line functions allow for great flexibility, it’s difficult to write with them. Luckily, the Canvas API also allows for text to be written in either the “Stroke” or “Fill” methods listed above. Only one reference point is needed as well, which is specified in the text-writing function itself. What does need to be specified though, is the font.

// Stroke "Hello World" in grey at coordinates 10,100
ctx.strokeStyle = "rgba(128,128,128,1)";
ctx.lineWidth = 3;
ctx.font = "40pt Arial";
ctx.strokeText("Hello World", 10, 200);

// Paint “Hello World” in black at coordinate 10,150
ctx.fillStyle = “rgba(0,0,0,1)”;
ctx.font = “20px Arial”;
ctx.fillText(“Hello World”, 10, 150);

With this basic functionality it’s possible to make some nifty results:

Canvas Demo

See how this was done. Canvas also offers more advanced functionality such as saving/restoring the canvas, image exportation/importation and manipulation, and transformation effects such as rotation and skewing. A comprehensive documentation of usage and compatibility is covered on Mozilla Developer Central, including an overview and independent focuses on graphics and text. With this sort of dynamic control, developers have been hard at work experimenting with the possibilities of canvas for a while now and there is no sign of ingenuity stopping. The Times, They Are A-Changin’.

Comments

One response to “An Introduction to HTML5 Canvas”

  1. Cheyenne Saden Avatar

    Couldnt agree more with that, very valuable article

Leave a Reply

Discover more from Software by Steven

Subscribe now to keep reading and get access to the full archive.

Continue reading