Welcome to MSDN Blogs Sign in | Join | Help

Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Background

There's been some buzz about the upcoming HTML 5 standard over the past few months. In particular, there are a couple of new features that people are looking forward to. One of them is the new <canvas> element which introduces a 2D drawing API offering a pretty rich set of functionality. If you've worked with HTML much, you can probably imagine some of the things that become possible with this. In fact, those are probably some of the same things that Flash and Silverlight are being used for today! So some people have gone as far as to suggest HTML 5 could eliminate the need for Flash and Silverlight...

I didn't know much about the <canvas> element and I wanted to understand the situation better, so I did some research. The specification for <canvas> is available from two sources: the W3C and the WHATWG. (The two groups are working together, so the spec is the same on both sites.) The API is comprised of something close to 100 interfaces, properties, and methods and offers an immediate mode programming model that's superficially similar to the Windows GDI API. At a very high level, the following concepts are defined (though Philip Taylor did some investigation a while back which suggested that no browser offered complete support):

  • Paths and shapes (move/line/curve/arc/clipping/etc.)
  • Strokes and fills (using solid colors/gradients/images/etc.)
  • Images
  • Context save/restore
  • Transformations (scale/rotate/translate/etc.)
  • Compositing (alpha/blending/etc.)
  • Text (font/alignment/measure/etc.)
  • Pixel-level manipulation
  • Shadows

There's a variety of stuff there - and as I read through the list, I was struck by how much of it is natively supported by Silverlight. Pretty much all of it, in fact! :) So I thought it might be a fun and interesting learning experience to try implementing the HTML 5 <canvas> specification in Silverlight! What better way to understand the capabilities of <canvas> than to implement them, right?

So I went off and started coding... I didn't set out to support everything and I didn't set out to write the most efficient code (in fact, some of what's there is decidedly inefficient!) - I just set out to implement enough of the specification to run some sample apps and see how hard it was.

And it turns out to have been pretty easy! Thanks to Silverlight's HTML Bridge, I had no trouble creating a Silverlight object that looks just like a <canvas> to JavaScript code running on a web page. So similar, in fact, that I'm able to run some pretty cool sample applications on my own <canvas> simply by tweaking the HTML to instantiate a Silverlight <canvas> instead of the browser's <canvas>. And as a nice side effect, Internet Explorer "magically" gains support for the <canvas> tag!

Aside: Yes, I know I'm not the first person to add <canvas> support to IE. :)

 

Samples

I started off easy by working my way through the Mozilla Developer Center's Canvas tutorial and implementing missing features until each of the samples loaded and rendered successfully. Here are three of my favorite samples as rendered by Html5Canvas, my custom <canvas> implementation:

Mozilla samples

 

Aside: It's important to note that I did NOT change the JavaScript of these (or any other) samples - I just tweaked the HTML host page to load my <canvas> implementation. My goal was API- and feature-level parity; a Silverlight implementation of <canvas> that was "plug-compatible" with the existing offerings.

 

After that, I knew I just had to run Ben Joffe's Canvascape "3D Walker" because it bears a striking resemblance to one of the games I played when I was younger:

Canvascape

 

Aside: Be sure to look for the "Silverlight" context menu item I've included in the image above and in the next few screen shots to prove there's no trickery going on. :)

 

Next up was Bill Mill's Canvas Tutorial - and another shout-out to hours of misspent youth:

Canvas Tutorial

 

For something completely different, I got Bjoern Lindberg's Blob Sallad running:

Blob Sallad

 

Then it was on to Ryan Alexander's Chrome Canopy fractal zoomer (despite the note, it runs okay-ish in IE8 with my Silverlight <canvas>):

Chrome Canopy

 

Finally, I wanted to see how the 9elements HTML5 Canvas Experiment ran:

Canvas Experiment

 

Whew, What a rush - those apps are really cool! :)

 

But I still wanted a sample I could include with the source code download, so I also wrote a little app to exercise most of the APIs supported by Html5Canvas (thanks to Mozilla for the Hypotrochoid animation inspiration and Wikipedia for the equation). Here it is on IE:

Sample application in IE

 

And wouldn't it be nice to see how Html5Canvas compares to a "real" <canvas> implementation? Sure, here's my sample running on Firefox:

Sample application in Firefox

 

Details

So how does it actually work? Well, I'm obviously not modifying the browser itself, so redefining the actual <canvas> tag isn't an option. Instead, I've written a simple Html5Canvas.js file which gets referenced at the top of the HTML page:

<script type="text/javascript" src="Html5Canvas.js"></script>

Among other things, it defines the handy function InsertCanvasObject(id, width, height, action) function which can be used to insert a Silverlight <canvas> thusly:

<script type="text/javascript">
    InsertCanvasObject("mycanvas", 200, 200, onCanvasLoad);
</script>

That code inserts a Silverlight object running Html5Canvas.xap that looks just like the <canvas> tag would have. Yep, it's that easy!

And it brings up an important difference between Html5Canvas and a real <canvas>: Html5Canvas can be used only after the Silverlight object has loaded - whereas <canvas> is usable as soon as the body/window has loaded (which happens sooner). This distinction is important to keep in mind if you're converting an existing page, because it requires moving the initialization call from onload to the action parameter of InsertCanvasObject. Believe it or not, that's really the only big "gotcha"!

Aside: While I could think of a few ways to avoid exposing this difference to the developer, none of them were general enough to apply universally.

Other minor differences between Html5Canvas and <canvas> are that Silverlight doesn't natively support the relevant repeat modes used by createPattern to tile images (though I could implement them without much difficulty), Silverlight doesn't support the GIF image format for use with drawImage (also easily worked around), and the conventional technique of JavaScript feature-detection by writing if (canvas.toDataURL) { ... } doesn't work because Silverlight's HTML Bridge doesn't allow a method to be treated like a property (I could work around this, too, but the extra level of indirection was unnecessarily confusing for a sample app).

Finally, let me reiterate that I did not attempt to implement the complete <canvas> specification. Instead, I implemented just enough to support the first 5 (of 6 total) Mozilla sample pages as well as the handful of applications shown above. Specifically, I've implemented everything that's not in italics in the feature list at the beginning of this post. Thinking about what it would take to add the stuff that's not implemented: text and pixel-level manipulation are both directly supported by Silverlight and should be pretty easy. Shadows seem like a natural fit for Silverlight's pixel shader support (though I haven't played around with it yet). All that's left is layer compositing, which does worry me just a little... I haven't thought about it much, but this seems like another job for WriteableBitmap, perhaps.

 

[Please click here to download the complete source code to Html5Canvas and the sample application shown above.]

Be sure to set the Html5Canvas.Web project as the active project and run the TestPage.html within it to see the sample application.

 

Summary

Html5Canvas was a fun project that definitely accomplished its goal of bringing me up to speed on HTML 5's <canvas> element! The implementation proved to be fairly straightforward, though there were a couple of challenging bits that ended up being good learning opportunities. :) The code I'm sharing here is intended to be a proof-of-concept and is not optimized for performance. However, if there's interest in making broader use of Html5Canvas, I have some ideas that should really improve things...

I hope folks find this all as interesting as I did - and maybe next time you want to add browser features, you'll use Silverlight, too! ;)

Published Monday, August 24, 2009 1:26 PM by Delay
Filed under: ,

Comments

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Tuesday, August 25, 2009 7:31 AM by rbirkby

I don't see a license to this code. Is it unlicensed? It would be nice to Ms-PL it.

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Tuesday, August 25, 2009 1:09 PM by Delay

rbirkby,

This code is already licensed under Ms-PL. :)

(The "News" section in the column on the right side of my blog is where I call this out.)

Thanks!

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Tuesday, August 25, 2009 4:24 PM by chadbr

You are an animal. Impressive work.

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Tuesday, August 25, 2009 4:33 PM by Delay

LOL, thanks chadbr! :)

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Wednesday, August 26, 2009 8:44 AM by zachleat

Are there any statistics on Silverlight adoption percentages for Internet Explorer users?

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Wednesday, August 26, 2009 11:48 AM by benjoffe

For testing purposes my current PC is using IE7 (with silverlight) but your sample demo is not working with it. Have you tested this with IE 6 and 7?

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Wednesday, August 26, 2009 1:12 PM by Delay

zachleat,

I've seen various companies report adoption percentages and I honestly don't know which ones are most accurate. I think I remember hearing that something like 1/3 machines had Silverlight installed a few months ago, so it's probably at least that by now.

benjoffe,

I've tested with Win7/IE8, W2K8/IE8, and Win7/Firefox 3.5. However, I'd be pretty surprised if things didn't "just work" on IE7. Yours is the first report of this I've had - could you maybe follow up with me directly (use the "Email" link at the top right and I'll reply to you) and we can try to sort out what's causing you trouble.

Thanks!

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Wednesday, August 26, 2009 1:35 PM by fabien.menager

@benjoffe Did you run the sample demo from Visual Web Developer ? First time I tried the sample demo I just ran it on the browser, without running it from VWD and it didn't work (of course, the Silverlight file must be compiled).

@Delay Nice work, but the first Silverlight canvas with the colored squares doesn't seem to work here (and it throws an unhandled exception).

Could you add the sample demos you are showing us on this page to the zip?

Wouldn't you be interested in working with the ExCanvas team to make a very good <canvas> implementation for IE (which would work with or without SL)?

Finally, I'd really like <canvas> to be implemented in IE, without the need for a plugin, that only 1/3 of the browsers have.

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Wednesday, August 26, 2009 4:22 PM by Delay

fabien.menager,

I've just re-verified the ZIP download on my machine and uploaded the resulting files so that everyone can run them without having to compile first. So I don't think it's the ZIP that's causing problems. Could you please try the following link which should load fine for you in IE or Firefox if you've got Silverlight 3 installed:

http://cesso.org/Samples/Html5Canvas/TestPage.html

If you have a problem running the samples from that link, could you please contact me via the "Email" link and let me know what the specifics of the error are? Thanks.

Regarding sharing the source of the applications I showed, I'm not doing that because I don't want to be in the place of redistributing someone else's stuff. The changes I made to get those samples running were really trivial find/replace-style stuff in the HTML files, so it should be fairly straightforward if that's what you're trying to do. Sorry for the inconvenience!

Regarding working on ExCanvas, my day job and blogging already consume pretty much all the free time I have. :)

Regarding native <canvas> support in IE, I agree that would be nice!. If this post helps that process along at all, I'll be pretty happy. :)

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Thursday, August 27, 2009 3:25 AM by Delay

benjoffe,

Is it possible that you ran into the same culture bug that Fabien reported above and which I've just fixed here:

http://blogs.msdn.com/delay/archive/2009/08/26/following-up-on-some-of-the-attention-live-sample-posted-and-a-very-small-tweak-to-the-html5canvas-source-code.aspx

If so, that would nicely wrap up both customer issues I've seen so far and I'd be a happy camper! :)

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Saturday, September 05, 2009 2:14 AM by Delay

# re: Using one platform to build another [HTML 5's canvas tag implemented using Silverlight!]

Thursday, September 10, 2009 2:05 AM by Delay
Anonymous comments are disabled
 
Page view tracker