Making HTML5 Come Alive with the Canvas API

14 Comments February 23, 2011


The last five years of my career have been devoted to Silverlight. I began working with it long before version 1.0 was released, and with Silverlight 5 on the horizon, I’m even more excited about it today than I was then. The fact that you can write phone apps with it is icing on the cake and the number one reason I’m bullish about Silverlight’s future and about the long-term prospects for Windows phones. I am honored and privileged to teach Silverlight and Silverlight for Windows Phone to Microsoft developers on campuses around the world, and every time I step into the classroom, I’m as excited and enthused as I was the very first time I pulled up a PowerPoint and said “Let me tell you how Silverlight is going to change your life.”

But while I was immersed in Silverlight, a funny thing happened: HTML5 came on like gangbusters. Microsoft and Apple execs seem to think HTML5 is the greatest thing since sliced bread. If you know me, you know how I feel about HTML and JavaScript. They’re fine for applets and Web pages, but building enterprise applications with them is another matter altogether. I’ll take C# any day over scripting languages. I like to be able to compile my code and make sure there are no syntax errors. I like to be able to test it and step through it in a debugger. JavaScript dev tools have come a long way in recent years, but they’re still a far cry from what you get out of the box with Visual Studio and C#.

HTML5 seems destined to play a huge role in the lives of software developers. It won’t be used just to build Web pages; it’ll be used to build browser-based applications, phone applications, applications for iPads and other slate devices, and yes, even enterprise applications. So I decided it’s time to dive in. Silverlight will still be my primary focus for the foreseeable future, but HTML5 will have a strong secondary focus. I’m scheduled to deliver my first HTML5 class on Microsoft’s Redmond campus in early April. I’m writing that course right now and am generally having a fun time doing it. Soon, it’ll be available to the public as well. And when people ask me how HTML5 compares to Silverlight, I’ll be able to offer a knowledgeable apples-to-apples assessment.

The feature of HTML5 that I find the most interesting and compelling is the canvas API. After all these years, developers are finally able to draw into a browser window without help from plug-ins. HTML5’s canvas API is reasonably well thought-out, and it even includes an equivalent to Silverlight’s WriteableBitmap, which allows apps to generate images on the fly and manipulate pixels destined for the frame buffer.

The starting point for HTML5’s canvas API is the new <canvas> element, which represents a pixel-addressable display surface. As a very simple example, suppose you wanted to draw a red rectangle into a browser window. You’d start by declaring a <canvas> element, and then write a bit of JavaScript to get a drawing context and call the context’s fillRect method:

 

// HTML5

<canvas id="output" width="400" height="400" />

 

// JavaScript

var canvas = document.getElementById("output");

var dc = canvas.getContext("2d");

dc.fillStyle = "red";

dc.fillRect(100, 50, 200, 100);

 

Of course, you can do much more than draw rectangles. You can draw lines, arcs, paths, text, images, and more. You can draw drop shadows, use alpha values, and apply transforms that are similar to the transforms you may be familiar with in XAML. You can perform pixel manipulations on what you’ve drawn, and you can use Boolean operators to composite shapes. In short, the canvas API is a rich one that opens the door to all kinds of interesting new HTML-only applications. And in the future, HTML will likely support 3D drawing operations as well as 2D operations. Imagine doing real 3D in the browser without any plug-ins!

To demonstrate key facets of the canvas API, I built a couple of samples and posted them on Wintellect’s Web site. The first is an HTML5 port of the venerable Visual C++ Scribble application from years ago:

Scribble

Use the left mouse button to draw, or double-click the chalkboard to clear it and start another masterpiece. If you’d like to try it out, point your favorite HTML5 browser such as IE9, Chrome, or Firefox 4.0 to http://www.wintellect.com/html5/scribble.html. I won’t reprint the source code here because you can see it for yourself with View Source. If you do, you’ll see that there’s not a whole lot to it. I used jQuery to handle mouse events because I didn’t want to have to write a boatload of code to make mouse handling work consistently in different browsers. And I used the little trick of assigning a value to a canvas’s width or height property to reset the canvas and erase everything in it.

The second example is an HTML5 Mandelbrot-set viewer. Here it is in Chrome:

Screen3 Screen4

It works in all three browsers, too, but IE9 doesn’t display the rectangular cursor used for zooming. If you run this app in IE9, you’ll have to imagine that the cursor points to the upper-left corner of a 100-by-100-pixel selection rectangle. The region inside the rectangle is what you’ll zoom into if you click.

The app is posted at http://www.wintellect.com/html5/mandelbrot.html. Once more, View Source is all that’s required to reveal the magic. This time I’m using HTML5’s createImageData and putImageData methods to generate bitmaps on the fly and display them in the browser.

Something that surprised me about the Mandelbrot app is the performance. The code that generates the fractal image loops through each and every pixel up to 128 times. Depending on the size of the browser window and the region of the Mandelbrot set you’re viewing, Chrome can take up to 3 or 4 seconds to render a new view, which isn’t bad considering the computational effort involved. Firefox, however, is astonishingly fast, typically generating an entire view in less than a second on my dual-core PC. This is a testament to how far JavaScript has come in terms of performance in modern browsers. Of the three browsers, IE9 is the least performant, often taking 5 seconds or more to render what Firefox renders in half a second.

Look for more blog posts in the future about HTML5 and how to leverage its most compelling new features.

Update: When I originally posted this article, I said that the sample apps don’t work in IE9. Turns out that was because I didn’t include the simplified HTML5 DOCTYPE element at the top of the files. Chrome and Firefox didn’t care, but IE9 cared greatly. The lesson is simple: when you author HTML5 pages, be sure to start them off with <!DOCTYPE html>.


14 Comments

  • Gravatar Image
    Tim February 23, 2011 2:02 PM

    Just curious if you could expand on why it doesn't work in IE9. What support is the RC missing in order to make these work?

    Just seems like they've done so much work on it that it's a shame that it doesn't work for such trivial (not to downplay your work, but they are fairly simple ideas) examples.

  • Gravatar Image
    Twitter Trackbacks for Jeff Prosise's Blog : Making HTML5 Come Alive with the Canvas API [wintellect.com] on Topsy.com February 23, 2011 3:06 PM

    PingBack from http://topsy.com/www.wintellect.com/CS/blogs/jprosise/archive/2011/02/23/making-html5-come-alive-with-the-canvas-api.aspx?utm_source=pingback&utm_campaign=L2

  • Gravatar Image
    Bob F February 23, 2011 5:16 PM

    It would be interesting to know the render time of the Mandelbrot app using Silverlight with a shader to perform the pixel manipulation.

  • Gravatar Image
    jprosise February 23, 2011 6:11 PM

    A Silverlight pixel shader would be slow because shaders aren't GPU-accelerated, but I have a Silverlight version of the Mandelbrot app that uses WriteableBitmap. I'll try to do some benchmarks because the speed of Firefox really surprised me.

    RE: IE9. Turns out that if you include the DOCTYPE element, IE9 runs the apps. But adding it breaks other things. I'm working on resolving the incompatibilities so the apps will work on all three platforms. Update soon.

  • Gravatar Image
    Joe February 23, 2011 11:25 PM

    Sorry, I find it hard to get excited about imperative graphics programming again. Where's the Microsoft HTML5 framework to make all this useful?

  • Gravatar Image
    brad February 24, 2011 5:16 AM

    That is all well and good, just remember how much faster that fractal render is in software. It is almost 2 full orders of magnitude faster as a native implementation. HTML5 would have been cool... 5 years ago.

  • Gravatar Image
    jprosise February 24, 2011 7:23 AM

    > HTML5 would have been cool... 5 years ago.

    Funny...I've said the same thing before, but quoted 10 years instead of 5. :-)

    > just remember how much faster that fractal render is in [native code]

    Agreed. I was (and still am) skeptical about doing this kind of thing in JavaScript. Firefox blew me away, though. It appears to be about one order of magnitude faster than IE9.

  • Gravatar Image
    Scott Seely February 24, 2011 7:44 AM

    Jeff- This is running in IE9 for me. 9.0.8080.16413, running in 32 bits on Win7.

  • Gravatar Image
    jprosise February 24, 2011 10:24 AM

    Scott, it's now running in IE9 since I added the DOCTYPE element I didn't include the first time around.

    Try it in Firefox 4.0 Beta 11. The performance is amazing!

  • Gravatar Image
    David Easton February 25, 2011 7:00 AM

    It is very speedy in Opera (11.01) too.

  • Gravatar Image
    Jeff Prosise's Blog April 3, 2011 8:36 PM

    HTML5’s Canvas and CanvasRenderingContext2d bring something to HTML5 that has long been missing from

  • Gravatar Image
    Jaa April 21, 2011 9:45 AM

    What Ide does eveyrone use to debug this code, ie step through it line by line to inspect values etc?

  • Gravatar Image
    jprosise April 21, 2011 3:55 PM

    Yes, pretty much. Newer browsers make it relatively easy. In IE9, for example, press F12 to get a great debugging console. For Firefox, use Firebug.

  • Gravatar Image
    Jaa April 22, 2011 7:13 AM

    In that case, I have another question...

    If you write some super-fantastic code, what is stopping someone else pressing F12 in IE9 and pinching it?

Have a Comment?

Archives

Tags

Blogs