HTML5 Canvas Example

by William Malone

With HTML5 support emerging, I have decided to investigate the drawing capabilities. In the tutorial I will focus on drawing on the new element called a "canvas". I created an example icon in Photoshop and will reproduce it by drawing on a canvas with JavaScript.

Html5 Canvas Example

Browser Capability

At the time of this article HTML5 is not yet standard and not fully supported by the major browsers. Despite my attempts to keep my example consistent between browsers, there were some aspects I was unable to overcome. Let's take a look:

Browser Comparison *Internet Explorer 8.0 with use of ExplorerCanvas

Browser consistency added a lot of extra complexity and code. To better understand the basics of html5 canvas let's take a more simple approach. Simplier also means less compatibility:

Browser Comparison Simple

Simple Example Implementation

We shrug off the browser capability issues for now (hopefully the future will bring full support in all browsers) so we can take a much simpler look at how this example was created.

Markup

First let's take a look at the markup:

<canvas id="canvasId" width="165" height="145"></canvas>

Now we have a blank canvas. Not very useful on its own, but in comes JavaScript.

Script

The canvas element will provide an area on which we will use JavaScript to place our drawing. You don't draw on the canvas, just like you wouldn't draw on your table. You draw on something on the table. That 'something' is the context.

var context = document.getElementById("canvasId").getContext("2d");

The method getContext with the parameter "2d" gives access to the canvas context. Now we can start drawing! Let's create a triangle:

var width = 125;  // Triangle Width
var height = 105; // Triangle Height
var padding = 20;

// Draw a path
context.beginPath();
context.moveTo(padding + width/2, padding);        // Top Corner
context.lineTo(padding + width, height + padding); // Bottom Right
context.lineTo(padding, height + padding);         // Bottom Left
context.closePath();

// Fill the path
context.fillStyle = "#ffc821";
context.fill();
Step 1

Our triangle looks a little flat. Instead of a solid color, let's fill it with a linear gradient. First create the gradient using context's method createLinearGradient. The gradient's method addColorStop specifies the gradient's colors.

// Create fill gradient
var gradient = context.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0, "#ffc821");
gradient.addColorStop(1, "#faf100");
	
// Fill the path
context.fillStyle = gradient;
context.fill();
Step 2

Now to add a shadow by setting a couple of properties on context: shadowBlur and shadowColor. Note: Make sure you specify these properties before filling.

// Create fill gradient
//...

// Add a shadow around the object
context.shadowBlur = 10;
context.shadowColor = "black";

// Fill the path
// ...
Step 3

A horizon gradient is added going from transparent, immediately to a color then fading back to the background color.

// Add a horizon reflection with a gradient to transparent
gradient = context.createLinearGradient(0,padding,0,padding+height);
gradient.addColorStop(0.5, "transparent");
gradient.addColorStop(0.5, "#dcaa09"); 
gradient.addColorStop(1, "#faf100");

// Fill the path
context.fillStyle = gradient;
context.fill();
Step 4

Add the black stroke outline:

// Stroke the inner outline
context.lineWidth = 5;
context.lineJoin = "round";	
context.strokeStyle = "#333";
context.stroke();
Step 5

Next we utilize another stroke with the background color to avoid drawing the rounded corners by hand.

context.lineWidth = 20;
context.lineJoin = "round";	
context.strokeStyle = gradient;
context.stroke();
Step 6

Add the exclamation point using context's fillText method. Don't forget the try / catch to stop Internet Explorer 8.0 from going to error town.

context.textAlign = "center";
context.textBaseline = "middle";
context.font = "bold 60px 'Times New Roman', Times, serif";
context.fillStyle = gradient;
try{
    context.fillText("!", canvasWidth/2, padding + height/1.5);
}catch(ex){}
Step 7

There you have it! Not exactly the same as our starting point, not supported by all browsers, but a good example of what html5 canvas has to offer.

Code for Simple Example

Before using this code, remember the limitation of this simple example:

Browser Comparison Simple

Markup


<!DOCTYPE html>
<html>
  <head>
    <title>HTML5 Canvas Example</title>
    <script type="text/javascript" src="simpleExample.js"></script>
  </head>
  <body>
    <canvas id="canvasId" width="165" height="145"></canvas>
  </body>
</html>

Script

var context = document.getElementById('canvasId').getContext("2d");
	
// Dimensions of the triangle
var width = 125;
var height = 100;
var padding = 20;
	
// Create a triangluar path
context.beginPath();
context.moveTo(padding + width/2, padding);
context.lineTo(padding + width, height + padding);
context.lineTo(padding, height + padding);
context.closePath();
	
// Create fill gradient
var gradient = context.createLinearGradient(0,0,0,height);
gradient.addColorStop(0, primaryColor);
gradient.addColorStop(1, secondaryColor);
	
// Add a shadow around the object
context.shadowBlur = 10;
context.shadowColor = "black";
	
// Stroke the outer outline
context.lineWidth = lineWidth * 2;
context.lineJoin = "round";	
context.strokeStyle = gradient;
context.stroke();
	
// Turn off the shadow, or all future fills will have shadows
context.shadowColor = "transparent";
	
// Fill the path
context.fillStyle = gradient;
context.fill();

// Add a horizon reflection with a gradient to transparent
gradient=context.createLinearGradient(0,padding,0,padding+height);
gradient.addColorStop(0, "transparent");
gradient.addColorStop(0.5, "transparent");
gradient.addColorStop(0.5, tertiaryColor);
gradient.addColorStop(1, secondaryColor);

context.fillStyle = gradient;
context.fill();
	
// Stroke the inner outline
context.lineWidth = lineWidth;
context.lineJoin = "round";	
context.strokeStyle = "#333";
context.stroke();

// Draw the text exclamation point
context.textAlign = "center";
context.textBaseline = "middle";
context.font = "bold 60px 'Times New Roman', Times, serif";
context.fillStyle = "#333";
try{
context.fillText("!", padding + width/2, padding + height/1.5);
}catch(ex){}

Cross-Browser Example

The cross-browser example requires more complicated code (especially to support Internet Explorer 8). After all that there are still browser compatibility issues:

Browser Comparison *Internet Explorer 8.0 with use of ExplorerCanvas

To achieve a more cross-browser friendly version, I use a few tricks to handle the differences in shadows, including using bezier and quadratic curves. You can download the source for both examples below.

Html5 Canvas Example

Download Source

The iPhone does not currently support downloads.

References

Related Articles

Share this Article