Sunday, January 23, 2011

HTML5 Canvas

One of the exciting features of HTML5 is the promise of universally supported animation and graphics via the new canvas element/tag. In this post, I look at how easy it is to use this tag with a simple example. I also demonstrate how well it is supported in five major web browsers.

The following HTML/JavaScript example illustrate <canvas>'s ease of use.

<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>HTML5 Canvas Demonstrated</title>
  <script language="javascript">
  var context;
  function initializeCanvas()
  {
     var canvas = document.getElementById("canvas1");
     context = canvas.getContext("2d");
     canvas.width = canvas.width;  // reset
  }

  function drawRectangle()
  {
     context.fillStyle = "black";
     context.fillRect(70, 25, 150, 50);
  }

  function addText()
  {
    context.fillText("RMOUG", 250, 40);
    context.fillText("Dustin", 125, 100);
  }

  function addGradient()
  {
     var gradient = context.createLinearGradient(125, 115, 250, 225);
     gradient.addColorStop(0, "red");
     gradient.addColorStop(1, "blue");
     context.fillStyle = gradient;
     context.fillRect(125, 115, 250, 225);
  }

  function addDrawnLinePath()
  {
     context.moveTo(10, 250);
     context.lineTo(10, 400);
     context.lineTo(30, 250);
     context.lineTo(30, 400);
     context.lineTo(50, 250);
     context.lineTo(50, 400);
     context.lineTo(75, 225);
     context.lineTo(10, 250);
     context.strokeStyle = "#000000";
     context.stroke();  // draw on path
  }

  function addDrawnCirclePath(fillIn)
  {
     context.beginPath();
     context.arc(150, 400, 25, 0, Math.PI * 2, false);
     context.closePath();
     context.strokeStyle = "green";
     context.stroke();
     if (fillIn)
     {
        context.fillStyle = "yellow";
        context.fill();
     }
  }
  </script>
</head>
<body onload="initializeCanvas()">
  <header>
    <h1>HTML5 Canvas Demonstrated</h1>
  </header>
  <canvas id="canvas1" width="400" height="500">
  </canvas>
  <form name="canvasForm">
     <input type="button" value="Draw Rectangle" onmousedown="drawRectangle()">
     <input type="button" value="Add Text" onmousedown="addText()">
     <input type="button" value="Add Gradient" onmousedown="addGradient()">
     <input type="button" value="Add Line Path" onmousedown="addDrawnLinePath()">
     <input type="button" value="Add Circle Path" onmousedown="addDrawnCirclePath(false)">
     <input type="button" value="Add Full Circle" onmousedown="addDrawnCirclePath(true)">
  </form>
</body>
</html>

The above example allows the user to click on a button at a time to see each different item drawn to the canvas. Rather than show each step here, I show the final result of pressing all buttons as rendered in Chrome 8, Firefox 3.6, Opera 11, and Safari 5. Internet Explorer 8 is covered separately later in the post.

Chrome 8


Firefox 3.6


Opera 11


Safari 5


Internet Explorer 8

Unfortunately, as the next image shows, Internet Explorer 8 does not render the above example as well as the others.


The What About IE? section of Dive Into HTML5's (free online version of book HTML5: Up and Running) chapter called Let's Call It A Draw(ing Surface) describes how to get around this in Internet Explorer 8. The suggestion there is to use explorercanvas, a project hosted on Google Code with the slogan "HTML5 Canvas for Internet Explorer." It's description states about explorercanvas:
Modern browsers like Firefox, Safari, Chrome and Opera support the HTML5 canvas tag to allow 2D command-based drawing. ExplorerCanvas brings the same functionality to Internet Explorer. To use, web developers only need to include a single script tag in their existing web pages.

The license for explorercanvas is Apache License 2.0, its downloaded ZIP file is less than 100 KB in size, and the Instructions wiki page demonstrates how easy it is to use.

The beauty of explorercanvas is that only one line needs to be added to the example above to allow Internet Explorer to support the <canvas> APIs similarly to the other browser. Here is that line (which is placed between the <head> and </head> tags), assuming that the downloaded excanvas.jar is in the same relative directory:

<!--[if IE]><script src="excanvas.js"></script><![endif]-->

When I add this to the HTML shown at the beginning of this post and reload the page in Internet Explorer 8, it (mostly) works! The newly rendered page taking advantage of explorercanvas is shown next.


The canvas text does not seem to work (no "RMOUG" or "Dustin" strings), but everything else appears to behave in Internet Explorer 8 thanks to explorercanvas.


Conclusion

The HTML5 <canvas> is one of the more consistently supported HTML5 features across the major browsers. Thanks to explorercanvas, even Internet Explorer 8 can largely support it. Besides being standard and consistent, the <canvas> functionality is easy to apply.

2 comments:

@DustinMarx said...

Rich W. Chan's (Literally) Drawing the HTML5 Logo in Canvas with JavaScript is highly relevant to this post and to my previous post on the HTML5 logo. Similarly, Daniel Davis's HTML5 Logo in HTML5 is particularly interesting because it shows how to use canvas's "moveTo" and "lineTo" to draw a high-quality HTML5 logo.

Dustin

Lindsley said...

I've made a couple of canvas tools that might be of interest to visitors here. One is a Font creator that make bitmap fonts that then load right into the canvas page. The other is called Canvas Path Maker. It creates simple paths and shapes, and then exports out as JS. They're both free! Please see them at
http://www.davidlindsley.com/canvastools.htm