Official website for Web Designer - defining the internet through beautiful design
FOLLOW US ON:
Author: Steve Jenkins
22nd October 2012

Beginners guide to HTML5 Canvas

The HTML5 Canvas element is arguably the most important addition to the next-gen specification, providing an array of possibilities for bringing graphical capabilities natively into the browser

Beginners guide to HTML5 Canvas

The HTML5 Canvas element is arguably the most important addition to the next-gen specification, providing an array of possibilities for bringing graphical capabilities natively into the browser. As well as helping to make UIs richer, it has fuelled some progressive web work that spans animation, video and games – with the latter providing some experimental projects that push visual boundaries and those for user interactivity.

By allowing designers and developers to create amazing 2D graphics with relatively little code opens up the door to some amazing possibilities in the field of image and video manipulation. This article defines what Canvas is all about, where it came from, what it means to work with and, perhaps most importantly, how some of its powerful functionality can be used in your own projects.

What is the Canvas tag?

Canvas is very different to the other elements which were introduced with HTML5 in that its purpose is to manipulate 2D bitmap graphics or create them from scratch. In comparison, other new elements – such as Video and Audio – are simply used to embed existing media into a website rather than creating something new. The Canvas element is also interesting because it is effectively useless without the accompanying Canvas JavaScript API.

A good way to look at the Canvas element is by comparing it to an Etch-a-Sketch mixed in with a bit of Microsoft Paint. The reason for this is that Canvas is a tool that acts as a simple 2D drawing environment with features much like the Etch-a-Sketch/Paint hybrid: with lines, shapes, curves, basic colour filling and stroking (outlining) of lines and shapes, among many others. Canvas is like an Etch-a-Sketch specifically because the only way to completely change what has been drawn on it is to wipe it clean and start again, just like shaking the much-loved drawing toy. This may seem odd but it’s a very simple technique and one that you get used to very quickly, particularly when working with animation.

It’s slightly unfair to describe Canvas as such a simplistic drawing tool when in reality it can do so much more – for example, it can be used to create dynamic graphics, animations, games and data visualisations; this is on top of the ability to provide basic manipulation of images and video. So in reality, with a bit of imagination, Canvas can become a potent tool for creating super-immersive and visually interesting experiences within the browser.

Given its graphical nature it’s not shocking to hear that Canvas was invented by Apple many years ago. They created it for use with the Dashboard widgets, like that little black-and-white clock that comes pre-installed. On the upside this meant Canvas was also available within WebKit so it could be used for websites, and it didn’t take long for other browsers to warm to the app and adopt it themselves.

It was only fairly recently that this element was actually accepted as an official specification and bundled within the collection of essential tags that make up HTML5. What’s great about this is that Canvas support must now be consistent in all the browsers that want to support it, which is very good news for developers wanting to use it.

Browser support

General support for Canvas is excellent in all major and modern browsers. The one exception is that Internet Explorer versions 8 and below have absolutely no support whatsoever. Although this will not be surprising to some people, the good thing is that Canvas support in IE9 and onwards is impressive and actually performs very well.

There are a couple of options for those of you who very much want Canvas functionality in IE8 and below. One workaround is the ExplorerCanvas JavaScript plug-in (http://code.google.com/p/explorercanvas), which basically replicates as much of Canvas as possible without requiring any changes to your code. Another option is FlashCanvas (http://flashcanvas.net), which falls back on Flash support and also requires very little setup. The problem with both of these methods is that absolutely everything in the Canvas specification is supported and performance can often be an issue for complex tasks like composite operations.

Looking back at native implementations of Canvas there are a few discrepancies between the browsers that support it. One area where things often get a little tricky is composite operations, simply because various browsers have implemented them in slightly different ways. For most developers this won’t be a problem but for those who come to rely on composite operations in Canvas you may get frustrated at the minor differences in implementation. It’s hoped that support for composite operations will become consistent in the near future but there isn’t much you can do about it for now.

Another area in which Canvas support can differ is with general performance, so as of today there are some browsers and platforms that can do things a little faster than others. The reason for this is often due to the lack of hardware acceleration, particularly on Mac browsers. Unfortunately browsers are finding it quite difficult to implement hardware acceleration on the Mac platform and so right now Canvas is often slightly faster on the same browsers in Windows. This is why IE performs so well, because it’s easier to do hardware acceleration on Windows rather than it being something special about IE. Consistent hardware acceleration across platforms is another thing that is being worked on and it’s likely that updates will be seen fairly imminently.

It’s important not to forget mobile support for Canvas as this is where the major differences in performance lay. Right now all the major mobile platforms support Canvas and the vast majority of its functionality. However, as a result of relatively slow mobile hardware and a lack of consistent hardware acceleration, performance on mobile devices varies considerably, to say the least. Therefore, you can expect any Canvas-intensive applications and animations to run much slower on mobile devices than they do on the desktop. There isn’t much that can be done about this for the time being apart from seeing if you can use DOM-based graphics and hardware-accelerated CSS3 transitions instead. Of course, as time goes on, mobile support will improve but it will always be limited by the power of the hardware.

Beginners guide to HTML5 Canvas

Silk is a Canvas application that combines lots of simple drawing techniques to produce something
visually stunning

Anatomy of the element

Using Canvas is really straightforward once you understand how its various pieces fit together. As a whole, Canvas comprises two major parts: the DOM element and the accompanying JavaScript API. The DOM element places the canvas on a page while the JavaScript API is the meaty bit that actually does the drawing and image manipulation.

Canvas DOM element

The Canvas DOM element is very simple and consists of very few components:

001 canvas width=””500”” height=””500””
002
003 /canvas

Now, this doesn’t do anything spectacular on its own but it does mean that you’ve included a full-blown HTML5 canvas within your page. To make it do something you need to access the JavaScript API, but for now it’s important to understand some of the quirks of the DOM element.

You’ll notice that there are explicit width and height attributes defined on the element. These dimensional attributes are required if you want to manually define the size of the canvas without having to rely on JavaScript. Leaving these attributes out will cause the canvas to adopt its default size of 300 pixels in width by 150 pixels in height.

It’s also important to know that defining the size of a canvas created using this tag with CSS will work, however it will actually stretch it rather than resize it. This is something that catches a lot of people out when they reach for CSS to rescale the canvas. The only way to truly resize the canvas is by editing the dimensional attributes on the element itself or through the JavaScript API.

2D rendering context

As mentioned previously the DOM element is only one part of Canvas – the other is the JavaScript API that accesses what’s known as the 2D rendering context. This is where everything on the canvas is actually drawn, while the DOM element is merely a window that displays part of the 2D rendering context. In fairness, the DOM element is a little more than just a window as it’s what provides all the JavaScript methods to draw on the 2D rendering context, but we’re keeping things simple here.

The 2D rendering context is much like the majority of other screen-based drawing platforms around in that it’s based on the Cartesian co-ordinate system. In Canvas the origin point of the co-ordinate system (0,0) is at the top-left and the co-ordinates move positively down and to the right. A general rule of thumb is that a single unit in the co-ordinate space amounts to one pixel on the screen.

Accessing the 2D rendering context with JavaScript is as easy as calling the getContext method of the Canvas DOM element, like so:

001 var canvas = document.getElementById(“myCanvas”);
var context = canvas.getContext(“2d”);

From here you have full access to all the various drawing and image-manipulation methods of the API. For example, calling the following method would create and place a small black square on the canvas:

001 context.fillRect(20, 20, 80, 80);

In just a few lines you’ve been able to draw a simple shape on the canvas, but there’s so much more to it than that, as we’re about to see…

Beginners guide to HTML5 Canvas
The 2D rendering context of Canvas uses a standard screen-based Cartesian
co-ordinate system

Canvas graphics principles

When you think about how few drawing methods there are available to Canvas it can be surprising to see the things that can be achieved with it.
The following are just a few select features that provide the building blocks for more advanced drawing and image manipulation.

Drawing basic geometry

You’ve just seen how to draw a square with the drawRect method of the 2D rendering context, but you can also use the same method to draw rectangles of any size in any position. The four arguments of the drawRect method are as follows:

001 context.drawRect(x, y, width, height);

The x and y arguments refer to where on the co-ordinate system the top-left corner of the rectangle will be drawn, and the width and height arguments refer to the dimensions of the shape in relation to the x and y positions. You don’t have to draw filled rectangles, as you can also make stroked (outlined) rectangles by calling the strokeRect method with the same arguments:

001 context.strokeRect(20, 20, 80, 80);

Aside from rectangles you can draw single lines – often referred to as paths – and build them up to create your own custom shapes. Drawing lines requires the use of a few methods: beginPath, moveTo, lineTo, closePath, fill and stroke. For example, you can create a simple line like this:

001 context.beginPath(); context.moveTo(20,20); context.lineTo(100, 100); context.closePath(); context.stroke();

This will draw a line from near the top-left of the canvas diagonally down to the right. There is much more to paths than this but the main thing is to understand that they are the foundation of more complex shapes in Canvas.

One other example of paths that has been made easy with a special method is drawing circles. To do this you would use the arc method alongside some of the path methods you saw previously:

001 context.beginPath(); context.arc(60, 60,40, 0, Math.PI*2, false); context.closePath(); context.fill();

Due to its relative complexity, it’s beyond the scope of this article to fully explain how circles work in Canvas but the alternative above would draw a full circle that is filled in with black. The following is a brief explanation of the arc method arguments:

001 context.arc(x, y, radius, startAngle, endAngle, antiClockwise);

The main difference between arc and other drawing methods is that the x and y co-ordinate values refer to the centre of the circle, whereas with, say, the rectangle they referred to the top-left corner. The startAngle and endAngle arguments are also interesting because they enable you to draw segments of a circle rather than the full thing.

Beginners guide to HTML5 Canvas

Canvas is also pivotal to rich web applications like this simple painting and drawing
editor at http://bomomo.com

Transformations

Aside from drawing there are various transform methods which each allow you to break free from some of the default constraints of Canvas. Transformations let you do things to the 2D rendering context, like translating its origin (normally top-left), scaling it so anything drawn will be larger/smaller and rotating it so things drawn onto it will be at an angle. To move the origin of the 2D rendering context you’d call the translate method with the desired x and y distance from the current origin:

001 context.translate(100, 100);

Now that the origin has been moved, anything that is drawn from this point onward at (0,0) will appear to be drawn at (100,100). This concept can be a little tricky to get your head around but it does make sense once you’ve tried it out yourself. To rescale the 2D rendering context you’d call the scale method and pass it x and y multiplier values:

001 context.scale(2, 2);

This would cause anything drawn from this point on to be twice the size than what it has been described as. It’s important to note that this affects the position as well as dimensional aspects of drawn elements. For example, with a scale of (2,2) a shape drawn at x and y position (10,10) will appear to be drawn at (20,20). Again, this begins to make more sense when you experiment with it yourself. Finally, to rotate the 2D rendering context you’d call the rotate method and pass it an angle in radians:

001 context.rotate(Math.PI/4);

This would twist the 2D rendering context by 45 degrees and cause anything drawn after this point to also be rotated by that amount. However, as well as appearing rotated, the shape will be drawn in a different position because the entire co-ordinate system has altered. Again, this is something that takes a little while to get used to and can be mitigated by combining rotate with the translate method to rotate a shape around a specific point. Learning how to fully utilise transformations is an integral part of being able to use Canvas to its full potential so it’s well worth spending some time getting to know them.

Gradient effects

Beginners guide to HTML5 CanvasUsing plain colour in Canvas couldn’t be simpler; it’s just a case of setting the fillStyle and strokeStyle arguments of the 2D rendering context with a legitimate colour value in much the same way as you would when working with CSS. However, you can also take advantage of fillStyle and strokeStyle to create gradated colours by utilising the createLinearGradient and createRadialGradient methods:

001 var gradient = context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, “rgb(0, 0, 0)”);
gradient.addColorStop(1, “rgb(255, 255,255)”);
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);

This will generate a linear gradient object that you can manipulate to display the colours you want. In this case the gradient will start with black at the top and end with white at the bottom (see image over the page). By applying the gradient object to the fillStyle property any shapes or paths drawn from this point on will also have a gradient fill.

Gradients in Canvas can be a little confusing to fully grasp – particularly radial gradients. The best way to get to grips with them is to play around with the code and see how they work in practice.

Loading images and video

One of the most powerful features of Canvas is its ability to display and manipulate images and video. You can load any image, HTML5 video element, or even another canvas directly into the one you’re working with or create your own with JavaScript:

001 var image = new Image(); image.onload = function() {context.drawImage(image, 0, 0); };
image.src = “myImage.jpg”;

The drawImage function can take a variety of arguments that define: where to draw the image, video or canvas, an area to crop the image to and the output dimensions to draw the image onto the canvas (allowing you to resize it, if you want).

Displaying images on the canvas is only the beginning. Things get really interesting when you access pixel-level data for the canvas using the getImageData method, edit those pixels somehow and draw them back to the canvas using the putImageData method. With this you could turn a colour video into black and white in real-time, or create a basic web-based image editor or whatever else you can imagine doing with pixels.
Mastering the manipulation of pixels in Canvas is a big step in turning it from a simple drawing platform into an incredibly powerful tool for displaying and editing visual media on the web.

Canvas in context

When talking about Canvas it’s important to put it in context with the other online technologies. Below we consider a few of the big players.

Canvas vs Flash

Canvas is often compared to Flash and sometimes referred to as a ‘Flash killer’, or it’s stated that Flash is better than Canvas. Both of these statements are irrelevant as the apps serve two different purposes.

Flash was created a long time ago when visual media on the web was in a pretty poor state. Since then it has evolved to solve issues surrounding things like animation, video and games. At the time of its creation there wasn’t anything like Canvas within the browser so Flash was the only option available. Flash was a lifeline for many web designers. Flash has since turned into a major platform for multimedia online and it won’t be going anywhere soon.
On the other hand, Canvas has been created to provide a method of drawing and manipulating visual media within a browser without an external plug-in. Part of the beauty of Canvas is that it is closely linked with HTML and JavaScript, which means that data can be quickly and easily shared between Canvas and other parts of a website or web app.

Canvas has been created to replace Flash – or to be more accurate, Canvas has been created to offer a legitimate alternative to Flash that fits the web in a better way. If you’re not developing for the web, or Canvas doesn’t do what you need it to, then using Flash is the only logical option open to you.
There is actually a lot that JavaScript developers can learn from Flash developers and it’s good to see this is already happening to some extent today. The Flash guys are the people who have been dealing with all the little visual-media issues for many years and have come up with lots of techniques to solve them. Canvas developers should embrace this knowledge rather than cast it aside.

CSS3 and jQuery

The other visual solutions on the web right now are CSS3 and jQuery; with CSS providing rich control of the styling of websites and jQuery allowing for slick animation and behavioural controls of media. Canvas is not here to replace either of these technologies – however it can complement them.
For example, there are some great jQuery plug-ins out there that utilise Canvas in some way or another. Flot (http://code.google.com/p/flot) is one that enables you to produce visually interesting graphs in Canvas while using the existing workflow that you’re familiar with in jQuery.

The creative canvas

Over the past few years there have been some incredible examples of Canvas in the wild. The following are just a few of the most interesting; find more on this regularly updated list of bookmarks: http://pinboard.in/u:robhawkes/t:canvas.

Using Canvas as CSS backgrounds on HTML5 Doctor

A powerful example of Canvas in action is the HTML5 Element Index on the HTML5 Doctor website (http://html5doctor.com). Canvas has been used to create custom rollover graphics on the fly for every single item in the navigation. Without Canvas this would have required tens – if not hundreds – of custom images. With Canvas this needed just a small amount of JavaScript and a bit of imagination.

Silk

One of the most beautiful examples of Canvas is the Silk experiment (http://weavesilk.com). Described as a magical artwork, Silk shows just how the simple drawing methods in Canvas can be combined to create a visually stunning interactive display.

Ever seen those TVs that have lights around the edge that make the wall behind appear to glow a similar colour to what’s playing on the screen? Well, this effect has been developed in Canvas for HTML5 video and it creates an incredibly immersive experience. For one example of this in action, visit http://paulrouget.com/bgvideo.
In a nutshell, each frame of the video is drawn onto a canvas and the pixel colour values are gathered in turn. Those values are then used to create a beautiful gradient background for the page that really makes the video stand out.

Wrapping up

That brings us to the end of our roundup of Canvas. The hope is that this brief overview of the mighty tag has given you an insight into its immense potential for the future of web design. It’s now impossible to ignore Canvas if you’re thinking about designing for the internet – particularly if you want to break away from the current reliance on software like Flash.

If Canvas excites you then we strongly encourage you to set aside some time to experiment with it. You’ll find that it’s not as difficult to learn as it may initially seem and you’ll be quickly impressed by the power and flexibility it can offer.
There’s no doubt that we’re only seeing the beginning of what’s possible on the web when technologies like Canvas are fully harnessed. With Canvas now being used in other areas like web games you can be confident that the future has some major developments in store for this element.

MAJOR FRAMEWORKS

EaselJS
http://easeljs.com

Encompassing ten key classes and with an API based on Flash’s display list, EaselJS is a beta JavaScript library for making Canvas development less cumbersome. In recognition of the existing element’s lack of internal concept for discrete display elements, EaselJS provides a retained graphics mode for Canvas including a full hierarchical display list, a core interaction model and helper classes to make working with Canvas more intuitive. Importantly it is also compatible with Android, iOS and those desktop browsers that already support the existing Canvas element. See page 48 for our tutorial on using EaselJS to create an interactive sprite.

appMobi directCanvas
www.appmobi.com

Very much geared towards mobile web game development, appMobi’s directCanvas improves rendering performance by eliminating typical overheads incurred by standard Canvas commands that are deemed redundant for gaming. Essentially a new canvas object, directCanvas is accessed in exactly the same way but delivers as much as 1,278 per cent speed boosts on the iPhone and 728 per cent increases on the iPad 2.

Paper.js
http://paperjs.org

Known as the ‘Swiss army knife of vector graphics scripting’, Paper.js is essentially an open-source framework that sits on top of Canvas. Developed by Jürg Lehni and Jonathan Puckey, it provides a scene graph and document object model (DOM) for handling vector graphics and specifically nested layers, groups, compound paths, rasters, symbols and more.

Tags: ,
  • Tell a Friend
  • Follow our Twitter to find out about all the latest web development, news, reviews, previews, interviews, features and a whole more.