In this post I’m going to talk about Canvas and Raphael and some of the important differences between them. Last year at some point I discovered Raphael… it’s an amazing drawing library that renders SVG or VML (for IE). One of the issues with canvas is that it doesn’t run in earlier versions of IE. A solution for this problem is excanvas, which will turn your canvas code into VML when it runs in IE – I used it for a few things and it works but has some weird problems. There are some really important differences between SVG/VML here are a few off the top of my head:
I’m just going to say SVG instead of SVG/VML all the time, but when I say SVG I mean both…
– canvas doesn’t have these built in so you have to write your own like in processing.
I’ve been working on a library for this that I’ll release at some point in the next few weeks
– SVG elements are part of the DOM so regular mouse events work the same way as they would on a div.
Pixels vs Vectors
– working with canvas is like painting, once you draw something, it’s on the canvas and if you want to erase it you have to draw over it.
This is great for drawing programs and photo-manipulation, but can be tricky for UI stuff and games (if you don’t just wipe the whole screen all the time which can be CPU intensive). Also, since we’re dealing with pixels, you can’t easily scale your canvas without losing image quality (there are work arounds for this of course, I just mean by default)
– with SVG, since we’re in vector graphics world, renderer looks at each element and figures out how to draw everything for you so you don’t need to worry about erasing the background every frame (you also have control of drawing order since the renderer just uses the order of elements in the DOM to determine how it draws things) – and SVG is obviously scalable…
This is great for UI elements, graphs and simple games, but can be tricky/useless for certain types of drawing programs and photo manipulation. Scaling graphics is easy, but Raphael doesn’t implement it exactly, so I wrote a helper script that allows you to easily scale your Raphael drawing,
– it’s very easy to save image files of your canvas element
– as far as I know you can’t rasterize SVG to an image file like jpg or png without the use of server-side code
You can pretty easily draw your SVG to a canvas element and save it that way (have a post about this in the pipeline)
– canvas has these built in with it’s save() and restore() functions
Among countless other things… this allows you to create parent-child relationships between elements.
– These exist in SVG too, but Raphael doesn’t implement them in a standard and familiar way so you have to hack it
– I haven’t done enough testing in this area, but there are a few things worth mentioning. On mobile devices SVG is noticeably smoother (at least on the iPhone) – I’ve recently been showing people my web app demos for class and some developers have asked me how I get things to run so smoothly (answer = Raphael and careful coding). If you have a complex vector graphic in SVG and your moving it around, it will run slowly, if you rasterize that same graphic and move it in the canvas it will run smoothly. You could of course just rasterize it and move it around in SVG as a image. If you are dynamically adding many static elements to your drawing during runtime, canvas will never slow down because your just changing pixel values, if you are doing this with SVG your increasing the number of DOM elements as well as the number of elements that need to go through the render pipeline – so SVG will eventually choke. One thing that has been floating around in my head recently is the idea of doing a Raphael/Canvas drawing app where you draw your shapes with SVG and then they get painted onto the canvas – may whip that up at some point.
There is a lot more to talk about here, things like text rendering and the advantages of DOM other than simple mouse events. Maybe in a later post….
I assume I’ll be doing more posts about Raphael and canvas in the future so to kick things off I thought I would do a simple syntax comparison. The below example renders a little oscillating string – just click anywhere to toggle rendering to the canvas or to Raphael:
Just right click and view frame source for the code.