HTML5 Tutorial – Drawing on Canvas

HTML5_Badge_256

The <canvas> element can be used to draw graphics via scripting in JavaScript. For example, it can be used to draw graphs, make photo compositions, create animations or even do real-time video processing or rendering. Canvas provicdes resolution-dependent bitmap canvas, which can be used for rendering images on the fly.

Because not all browsers support Canvas, I’ll use Modernizr to help out. Modernizr will let me know if Canvas is supported, and if not it will allow me to call a polyfill.

You can get started with Modernizr at Using Modernizr, Polyfills, YepNope.

But first, let’s draw something.

I can do this using <canvas> tag in HTML5. The HTML5 Canvas element is an HTML tag similar to the <div>, <a>, or <table> tag, with the exception that its contents are rendered with JavaScript.

Canvas is a simple graphics API that draws pixels and nothing more. Hence, there’s no way to change an existing drawing or react to events, such as a click, on a particular part of your drawing. You can respond to button events and then update the Canvas image by redrawing it.

Do this in three steps:

  1. Place the canvas tag somewhere inside your HTML
  2. Create an initializer JavaScript function that accesses the canvas tag once the page loads
  3. Draw on the HTML5 Canvas API.

But not all browsers support Canvas. Use Modernizr to check for canvas browser support, then load a polyfill when canvas is not supported by the browser.

Canvas Tag

Start by placing a canvas tag in your HTML, giving the canvas a width and height that represents the drawing surface.


<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>

Then add the Javascript initializer, which gets the document and provides a drawing context. https://gist.github.com/nextechu/9860774

The result is a line drawn on the canvas:

8132_image_thumb_7126700A

The Grid

You use JavaScript to draw on the canvas. The origin (at coordinate (0,0)) is in the upper left with the values increasing to the right and down. Normally 1 unit in the grid corresponds to 1 pixel on the canvas.

For example, you can draw a rectangle that if filled with the background color, clear the center, and then draw another inside it.


context.fillRect(25,25,100,100);
context.clearRect(45,45,60,60);
context.strokeRect(50,50,50,50);

Canvas supports a single shape, a rectangle. All other shapes must be created by combining one or more paths.

Paths

The first step to create a path is calling the beginPath method. Internally, paths are stored as a list of sub-paths (lines, arcs, etc) which together form a shape. Every time this method is called, the list is reset and we can start drawing new shapes.


context.beginPath();
context.lineWidth = 10;
context.fillStyle = "blue";
context.arc(305, 135, 10, 0, 360);
context.fill();
context.stroke();
context.closePath();

Save and Restore State

The canvas drawing state is basically a snapshot of all the styles and transformations that have been applied. You can save and restore the state.

Canvas states are stored on a stack. Every time the save method is called, the current drawing state is pushed onto the stack. A drawing state consists of

  • The transformations that have been applied, such as  translate, rotate and scale.
  • The values of strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation properties.
  • The current clipping path, which we’ll see in the next section.

You can call the save method as many times as you like.

Every time the restore method is called, the last saved state is returned from the stack and all saved settings are restored.

In this case, I am rotating the canvas to add rotated text.


context.save();
// rotate the context to draw at an angle
// the rotation is in radians
var degrees = 55;
context.rotate(degrees * 0.01745);
context.fillText("Main St", 150, -165);
// restore the context
context.restore();

save and restore also applies to transforms where you can stretch, scale, and transform your drawing.

6560_image_thumb_7E8C8310

And as you keep drawing, you can do this kind of thing:

IC547335

Detecting Canvas

Not all browsers support canvas.

Use Modernizr to detect whether canvas is supported and if the browser is not supported, you can use a polyfill.

According to the Modernizr Web site, a polyfill is “a JavaScript shim that replicates the standard API for older browsers.” “Standard API” refers to a given HTML5 technology or feature, like canvas. “JavaScript shim” implies that you can dynamically load JavaScript code or libraries that mimic those APIs in browsers that don’t support them.

Get a JavaScript library called excanvas, which adds canvas support at the API level to Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8. You can download excanvas from bit.ly/bSgyNR.

Then you can use feature detection to do the right thing using the canvas.


Modernizr.load({
test: Modernizr.canvas,
nope: '../Scripts/excanvas.js',
complete: function () {
Modernizr.load('Scripts/yourdrawing.js');
}
}]);

Modernizr tests whether or not the browser can display a canvas natively in the test parameter, and then loads the excanvas polyfill if it does not. Then, the code loads the drawing in JavaScript in Scripts/yourdrawing.js.

References

For more information, see No Browser Left Behind: An HTML5 Adoption Strategy.

For more information, see :

Sample Code

Sample code is available in the DevDays GitHub repository. See https://github.com/devdays/html5-tutorials