<canvas> element has a unique history. Starting out as an Apple creation and dating back to 2004,
canvas was eventually added to the official W3C HTML5 spec, becoming one of the most interesting and exciting parts of HTML5. It is used by web designers all over the world. Unfortunately, this element takes a bit of work to understand and, unlike your usual run-of-the-mill HTML elements, requires more than just static markup and styling. This element is great for sites looking for a more responsive web design, like maybe a realtor.
In this guide, I hope to get you started on understanding the
canvas element and what kinds of things are required and expected in its associated code. This should help you get a firm fundamental understanding of
canvas in preparation for creating something interesting and powerful with this unique HTML5 element.
Definition and Markup
I can’t possibly define the
canvas element better than the official W3C spec, so I’ll just quote part of that document here:
The canvas element provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly.
I also like the way Wikipedia describes its usage:
Canvas consists of a drawable region defined in HTML code with height and width attributes.
As you can see already, this element has a bit of complexity to it. Let’s take it one step at a time, beginning with the markup.
The markup for the
canvas element looks like this:
<canvas id="myCanvas" width="200" height="200"></canvas>
Similar to the
canvas has a width and height set in the markup to give it an actual size. And because
canvas requires scripting for its full capabilities, I’ve added an
canvas visible or, using CSS3
transition properties, move it around — the same as you would do with any other HTML element.
You can add a border, padding, background color, margins, you can float the
canvas, and assign CSS properties to it just like any HTML5 element.
Some Basic Scripting to Make It Work
To start drawing on a canvas, you need to first target it
using the Document Object Model (DOM). Since you can include more than one
canvas element on any given page, this is where an ID attribute comes into play (in this case, our ID is
canvas is targeted, the
canvas element, which means you will have access to the canvas drawing API. Here’s an example of code that draws an object on the canvas:
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); context.fillStyle = "rgba(0, 0, 255, .5)"; context.fillRect(25, 25, 125, 125);
After defining the
canvas element via the DOM (line 1), the context is defined (line 2), then a shape is drawn and colored (lines 3 and 4).
The first two lines are more or less standard stuff, whereas the third and fourth lines consist of a few examples of custom code using the properties and methods available in the drawing API. The four values given above in the
fillRect() method represent the distance from the x axis, the distance from the y axis, the width, and the height (in that order). The above code would generate a box like this: Having this rudimentary understanding of the
canvas element, here are some points of note:
canvaselement starts out blank, so it will not appear on the page until something is drawn on it or if it’s styled via CSS (e.g.
giving it a border or giving it a background color).
canvaselement appears in the DOM
- You can erase everything that is drawn on the
canvasby resetting the width and/or height of the
getContext()method “returns an object that exposes an API for drawing” (definition straight from the spec)
- There are currently two kinds of contexts available:
2dis currently the more commonly used context)
canvaselement is “resolution-dependent,” which means (unlike SVG) it will not always scale cleanly after rendering
- The default color for any shape drawn is black
- Canvas-drawn objects are given colors using RGBA or Hex values
Drawing Rectangles and Paths
fillStyle(color|pattern|gradient): Sets a fill style for the shape
fillRect(x,y,w,h): Draws a rectangle according to the given size and coordinate values and fills the object with whatever is defined in the fill style
clearRect(x,y,w,h): Clears the pixels inside the space defined by the given size and coordinate values
strokeStyle(color|pattern|gradient): Sets a stroke style for the shape
strokeRect(x,y,w,h): Draws the rectangle using strokes or borders (apart from the fill) according to the given size and coordinate values; this is done using the determined stroke style
Similar to the concept behind drawing rectangles, you can draw straight lines using the
These methods define, by means of x and y coordinates, the start and end points of the lines, or paths, that will be drawn. These methods, however, do not actually draw the visible lines; they prepare the
canvas for the actual stroking of the lines that will occur when you call the
stroke() method. Here’s a simple example:
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); context.moveTo(0, 0); context.lineTo(400, 400); context.strokeStyle = "#ff0000"; context.stroke();
Assuming the markup remains the same (with the canvas sized at 400×400), the code above (lines 3-6) draws a diagonal line from the top left corner of the canvas (0, 0) to the bottom right corner (400, 400).
The last line of code uses the aforementioned
stroke() method to stroke the path that was prepared on lines 3 and 4. Line 5 has the optional
strokeStyle method that can give the line a color, gradient, or pattern. If a stroke style is not declared, the line will be black by default. This is the line that is drawn by the code block above: Here are some further points to note about the drawing API:
- Coordinates that define paths and shapes can have decimal values, and this is encouraged to ensure line widths in certain circumstances are represented accurately
- To draw multiple paths in multiple stroke styles, you use the
beginPath()method for each line, then the
closePath()method to end the path after it’s drawn
- You can draw any Unicode character onto a
canvaselement, utilizing the
textBaselineattributes to style and align the characters
- If you don’t use the typographic attributes on text, the text will display using CSS styles applied to the
Linear and Radial Gradients
In step with what is now possible in CSS3 in most modern browsers, the
canvas drawing API allows you to fill your shapes and paths with two types of gradients.
Here is an example showing a rectangle being filled with a linear gradient:
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); var myGradient = context.createLinearGradient(0, 0, 100, 0); myGradient.addColorStop(0, "#cccccc"); myGradient.addColorStop(1, "#ffffff"); context.fillStyle = myGradient; context.fillRect(25, 25, 125, 125);
On line 3 above, the gradient is stored in memory and is given 4 arguments. The first two arguments are the x and y coordinates that determine the starting point of the gradient; the second two arguments are the x and y coordinates that determine the end point of the gradient. After the gradient is created (but not drawn yet), color stops are added (lines 4-5).
Then the fill style is defined on the canvas context, and the gradient that is created on line 3 is added as the value of the fill (line 5). After line 5, everything is just stored in memory, waiting to be used on a shape or path. The last line makes the gradient visible by creating a shape on which to place the gradient.
This is what the gradient looks like: Here are some notes on gradients:
- The position of the gradient is relative to the
canvas, not the shape (which seems a little odd at first)
- To make a diagonal gradient across an entire shape, the coordinates of the gradient would be identical to the coordinates and size of the shape
- The first and last color stops in a linear gradient are represented by 0 and 1, respectively; any additional color stops are represented by decimal values in between 0 and 1. Putting a color stop at 50% of the object, then, would be .5.
- Radial gradients are created using the
createRadialGradients()method, which takes 6 arguments; the first 3 arguments create a circle for the starting point, and the last 3 create a circle for the end point
Other Methods and Properties Available
What I’ve discussed so far are some of the methods and properties that are easier to deal with and understand. Canvas, however, has a much broader set of tools available in its drawing API. Here’s some of what’s available, with links to appropriate parts of the spec:
- Transformations, including scale and rotate
- Complex shapes, including Bezier curves and arcs
It’s strongly recommended that fallback content be used for non-supporting devices.
Fallback content is included by putting them between the opening and closing
<canvas> tags. For example, you might have something like this:
<canvas id="myCanvas" width="400" height="400"> <img src="images/fallback.jpg" alt="Fallback Content" width="400" height="400" /> </canvas>
This is a pretty simple example. If, for whatever reason,
canvas is unavailable, the user will see the
fallback.jpg image instead.
That image will not display if
canvas is supported.
A Basic Code Template for Canvas
Mozilla’s Developer Center has a great “skeleton” template for drawing
canvas elements. This is the template with some minor modifications.
First, it checks when the window has fully loaded, which means the DOM is ready to be worked on. This isn’t very efficient because the DOM will be ready even before the entire window is loaded, so on heavier pages, our function will take longer than it should to execute. The better solution would be to use
document.addEventListener with the argument of
DOMContentLoaded, but this isn’t supported in Internet Explorer (which wouldn’t really matter until IE9).
canvas element to call the
draw function (as in
Secondly, we use feature detection instead of browser sniffing to see if
canvas is supported. We do this with an if/else control structure. If
canvas.getContext is not null, then we can assume
canvas is supported and that it is ready to be worked on.
else) we can run some code in the event that
canvas is not supported (such as telling the user that the page requires a browser with
canvas support). For CSS, we just draw a black border around the area of the
canvas elements to make it easier to see. Then, finally, the HTML just involves giving the
canvas element an ID, width, and height.
Browser and Mobile Device Support
If you’re going to spend the time to create some sort of fallback content, then it would be good to know the extent of browser support for the
canvas element and its associated scripting.
canvas is supported in the following browsers and devices:
- Internet Explorer 9
- Firefox 3.0+
- Safari 3.0+
- Chrome 3.0+
- Opera 10.0+
- iPhone 1.0+
- Android 1.0+
What About Internet Explorer 6-8?
Using a third-party library called ExplorerCanvas,
From my limited experience in running some example pages included with the ExploreCanvas library, IE’s rendering of
canvas elements is very slow and resource-heavy, so unfortunately this workaround is not very inviting.
Why Use Canvas?
You might think that it’s a little counterproductive and counterintuitive to create simple objects using such complex means. Canvas, however, should not be utilized for static object creation.
Canvas is best used for drawing objects dynamically according to user input, or for updating the display of objects that are dependent on some kind of a dynamic feed of information (such as real-time stock market fluctuations visualized through a line graph).
HTML5 Canvas Examples
Although I’m not a huge fan of experimental techniques, it may be of value at this point to show what is possible with the
canvas element. Here are a few examples of apps and other experiments that do some interesting and downright cool stuff with HTML5
A virtual fish tank in your browser using attractive fish built without any graphic files.
It has realistic fish movements and bubbles. Click on the tank to add as many fish as you want!
An experiment taking HTML5
canvas to the next level. Each of the circle you see in the background is a Twitter user.
Click on a circle and you’ll see more information about that user. HTML5 Canvas and Audio Experiment
Agent 008 Ball
The international Billiards Tournament is being infiltrated by the terrorist organization CHALK.
Do not let them win! Sink as many balls as possible before the timer runs out.
This demo is an implementation of a full 8-bit color cycling engine, rendered into a 32-bit HTML5
canvas in real-time.
A simple motorcycle game using
Finally, here are some further articles, tutorials, and libraries that discuss or use the
- Canvas Toolkit: A basic HTML5
canvasdrawing library for those familiar with the java.awt.Graphics class in Java.
- The canvas element: discussed in Mark Pilgrim’s Dive Into HTML5
- RGraph: An HTML5 canvas graph library
- Processing.js: An open programming language for people who want to program images, animation, and interactions using the HTML5 canvas element
- <canvas> text: A library that allows canvas’s text-drawing methods to work in non-supporting browsers
- Canvas Demos: Home to applications, games, tools and tutorials that use the HTML5
- An Introduction to the Canvas 2D API: Tutorial on HTML5 Doctor
- Showcase of Games Developed Using HTML5 Canvas
If you know of any cool libraries, demos, or experiments that use the HTML5 canvas element, please let us know in the comments.