Getting Started on Line-of-Business HTML5 App – Part 5 Drawing on Canvas

A point-based representation of a surface.In this next section, I want to be able to provide a map of my business location. 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.

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>

And then add the Javascript initializer, which gets the document and provides a context.

 <!DOCTYPE HTML>
<html>
  <head>
    <script>
      window.onload = function() {
        var canvas = document.getElementById("myCanvas");
        var context = canvas.getContext("2d");

        // Write on the canvas here
         context.moveTo(100, 150); 

        context.lineTo(450, 50); 

        context.lineWidth = 15;

        context.stroke(); 
       };

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

The result is a line drawn on the canvas:

image

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.

 // save off the state of the context before rotating 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.

image

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

A point-based representation of a surface.

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.

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

Also, see the previous post in this series about Modernizr.

For More Information About Canvas

For more information, see :

Next Up

We’ll see how jQuery is designed to make it easier to navigate a document, select DOM elements, create animations, handle events, and develop Ajax applications.

 

Bruce D. KyleISV Developer Evangelist | Microsoft Corporation

image