SVG and canvas
Numerous people have suggested that SVG and <canvas> are competing technologies. They are not. SVG provides retained mode graphics and <canvas> provides immediate mode graphics. A lot of use cases can be addressed by either, but some are easier to do with one of them and some can only be done with one of them, and other cases are better when using both.
For any specific case, it is not always obvious which approach is best. This page lists a number of differences which may be relevant when designing a solution.
Advantages of SVG
- Editable static images
- SVG can be saved and loaded by standard vector editing programs. It is not possible to load <canvas> scripts, since they are not written declaratively.
- SVG can store additional non-visual information inside its normal structure ─ e.g. titles can be displayed as tooltips to give users more information when they move their mouse over an object, or can be read by speech synthesisers. <canvas> supports only a single alternative for the whole element, and authors must explicitly construct an accessible alternative in a language such as HTML.
- High-quality printing
- <canvas> renders onto a fixed-resolution bitmap, usually matching the screen's resolution. If the output is moved to a higher-resolution device (such as a printer), the <canvas> bitmap will appear pixellated, whereas SVG can automatically render a new high-resolution image.
- SVG can automatically detect interaction, such as clicking on an object. <canvas> can't, and authors must write their own code to convert mouse coordinates into the appropriate action.
- Mixing markup
- SVG can embed content from other namespaces, e.g. to include an XHTML fragment inside an image. <canvas> can't.
- There is no standard way to draw text in <canvas>. Alternative approaches are possible (e.g. overlaying HTML elements containing text, or drawing each character as a bitmap image) but are harder to use and less flexible. SVG does support embedded text.
Advantages of <canvas>
- Script-based scene graph
- If the scene is already stored as objects in script (e.g. to run a simple physics simulation on it, or to load it dynamically over a network) and does not exactly match the rendering hierarchy, it is easier to traverse that structure and render it using <canvas>, than to maintain a parallel SVG scene graph.
- Programmatic generation of images
- <canvas> is designed for creating images dynamically in scripts. SVG focuses on pre-computed image documents, and is more complex and slower to generate dynamically.
- Drawing pixels
- <canvas> works with pixels, and exposes them through functions like getImageData/putImageData. SVG works only with vectors, and pixel drawing has to be emulated inefficiently with tiny rectangles.
- Constant performance
- The memory usage of <canvas> is constant, whereas SVG uses more memory as you add more shapes. The time taken to draw a single shape onto a <canvas> is independent of what you have drawn before, whereas SVG becomes slower as the number of visible objects increases.
Combining SVG and <canvas>
There are cases where a combination is useful: e.g. a <canvas>-based game might load sprites from SVG images generated by a vector art program, to benefit from scalability and reduced download size compared to a PNG image; or a paint program might write its user interface in SVG, with an embedded <canvas> for the user to draw onto.
- Some implementations (Opera 9.5?) support SVG in <img>s, which can be used in the <canvas> drawImage method.
- Some implementations (future version of Opera?) support an extension of drawImage, where the argument is an SVGSVGElement instead of an HTMLImageElement.
- Some implementations (Opera 9.5? Firefox 3?) support <foreignObject> in SVG, which can contain XHTML that uses <canvas>.