June 2012

Volume 27 Number 06

Web Dev Report - Working with Graphics on the Web: Canvas vs. SVG

By Rachel Appel | June 2012

With the advent of Canvas and SVG (scalable vector graphics), developers now have better choices for doing graphics on the Web than in the past, when they had to implement myriad hacks and workarounds. Working with both graphics and design elements in Web development is now much easier for non-design-type developers because of technologies such as Canvas and SVG—and, of course, HTML5.

Before Canvas, plug-ins such as Flash or Silverlight were the standard way to create animations on the Web. The alternative was to create a collection of good old-fashioned HTML, JavaScript and images, and bundle them into a collection of moving parts—a tedious task at best.

Two primary types of graphics are used on the Web:

  • Raster graphics are arrays of pixels arranged on a grid, also known as a bitmap. Common raster file extensions are .jpg, .bmp, .png, .tiff and .psd. Because Canvas uses pixels, it is raster based.
  • Vector graphics use mathematical metadata contained in a file to describe the graphic. The V in SVG stands for vector. Common vector file types are .svg, .eps and .xps.

In this article I’ll investigate the advantages and disadvantages of both Canvas and SVG and recommend when you should use one rather than the other.

Canvasing the Neighborhood

Canvas is a scriptable Document Object Model (DOM) element that JavaScript developers can utilize for a variety of Web applications, from games, animations and data visualizations to mapping and more. Because Canvas is raster based, its API deals with pixel manipulation, making Canvas very flexible. Here are a few of the many common graphical tasks you can do with Canvas:

  • Render geometric shapes such as circles, rectangles and triangles
  • Render arcs and Bézier curves
  • Create games, puzzles and activities
  • Create dynamic, interactive data visualizations and graphs
  • Perform image editing, similar to Photoshop-style apps

Although <canvas> is a DOM element, working with it requires script. The only markup is the <canvas> element itself.

<canvas id="canvas" width="200" height="200"></canvas>

Browsing a Web page with only the <canvas> element inside it renders an empty space that looks much like an artist’s blank canvas. Because <canvas> is simply a container, its drawing context is where the real work takes place. To use Canvas, you must first retrieve either a 2D or a 3D context from <canvas> by calling getContext().

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

Proceed with caution when using the 3D context because it’s WebGL, and at the time of this writing, there is limited browser support for WebGL.

The context contains methods for creating and filling text, shapes, lines, arcs and other geometric figures complete with embellishments such as gradients and shadows. For example, the code in Figure 1 draws an atomic symbol on the <canvas> context.

<canvas id="canvas" width="200" height="200" style="border:1px solid">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
drawEllipse(.5,.5);
drawEllipse(.8,.8);
drawEllipse(.2,.2);
drawCenterCircle();
function drawEllipse(cos,sin) {
       var xCenter = 100;
       var yCenter = 100;
       var xPos, yPos;
       context.beginPath();
       for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.01 ) {
              xPos = xCenter - (35 * Math.sin(i)) * 
                Math.sin(sin * Math.PI) + (90 * Math.cos(i)) * 
                Math.cos(cos * Math.PI);
              yPos = yCenter + (90 * Math.cos(i)) * 
                 Math.sin(sin * Math.PI) + (35 * Math.sin(i)) * 
                 Math.cos(cos * Math.PI);
              if (i == 0) {
                     context.moveTo(xPos, yPos);
              } else {
                     context.lineTo(xPos, yPos);
              }
       }
              context.lineWidth = 2;
              context.strokeStyle = "#000";
              context.stroke();
              context.closePath();
}
function drawCircle() {
       context.beginPath();
       context.arc(100, 100, 10, 0, 2 * Math.PI, false);
       context.fillStyle = "#000";
       context.fill();
       context.lineWidth = 5;
       context.strokeStyle = "#000";
       context.stroke();
}
</script>


Figure 1 Atomic symbol in Canvas

As you can see, you can do just about anything with Canvas because of its flexibility. That flexibility comes with a price, however, and with Canvas, the cost is code volume and complexity. Converting the Canvas code from Figure 1 to SVG takes only about six lines of code (as you’ll see in Figure 3 in the next section). That’s a big difference!

Canvas games and image editing sites or apps often contain complex logic. To create complex Web sites and apps, libraries like EaselJSare easy to use and boost productivity by doing much of the legwork for you. EaselJS has helper classes and functions for working with CSS sprites, shapes, colors, image filters and image caching. Having these helpers available makes it easy to do complex, to-the-pixel graphic manipulations.

When it comes to accessibility, Canvas is challenging. The tag is a host for script, and the dynamic nature of script makes it impossible for the element to know and report its context’s activities to assistant software such as Microsoft Narrator.

Some browsers support GPU (graphics processing unit) offloading, otherwise known as hardware acceleration. Chakra, the Internet Explorer JavaScript engine in version 9 and greater, runs Canvas apps with the highest performance available because the GPU offloads script duty to the browser. Keep in mind that not all browsers currently support hardware acceleration, but those that don’t are quickly catching up.

Canvas is only one small piece of the massive set of specifications that are HTML5, so before you use Canvas in your Web sites, make sure to check browser support for Canvas. Once you start working with Canvas, don’t forget to use Modernizr for Canvas feature detection.

To SVG, or not to SVG?

SVG is both an HTML5 element and an API that has its own W3C standard for working with graphics. You can use SVG in your Web page by using the <svg> element or by referencing a .svg file with the src attribute of an <img> tag, like so:

<img src=”/path/atomic-symbol.svg” alt=”Atomic SVG”/>

The tag renders the .svg file as it would a .png or .jpg, but in addition, the .svg file scales when the user or software zooms in or out without pixilation on different-sized monitors and resolutions. This means that an SVG image keeps its integrity—that is, it stays crisp and clean. Raster images don’t maintain their clarity when resized. Figure 2 compares vector vs. raster when an image is zoomed.

The vector image on the left stays crisp when zoomed; the raster image on the right becomes blurry
Figure 2 The vector image on the left stays crisp when zoomed; the raster image on the right becomes blurry

SVG is part of the XML family of languages and focuses directly on two-dimensional graphics and images. For example, to generate an image of the atomic symbol, the SVG code inside a .svg file looks like the code in Figure 3, which is almost identical to the code inside an element. The only difference between the element and the SVG inside a file is the presence of the and

directives at the beginning of the .svg file. 

 

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
       <ellipse id="ellipse" cx="135" cy="153" rx="40" ry="110" 
           fill="none" stroke="#000" stroke-width="3"/>
       <circle cx="135" cy="155" r="10" stroke="#000" 
           stroke-width="5" fill="#000"/>
       <use xlink:href="# ellipse " transform="rotate(60 135,153)"/>
       <use xlink:href="# ellipse " transform="rotate(-60 135,153)"/>
</svg>

Atomic symbol saved in .svg file format
Figure 3 Atomic symbol saved in .svg file format

SVG is a markup language (XML), so that means file sizes can grow very large. On the plus side, declarative syntax means you can easily compress SVG in addition to searching and indexing SVG data.

Visio, Corel Draw and InkScape (OSS) are a few of the popular software packages that allow editing of SVG. Web sites such as graphviz.org and vectormagic.com make converting between formats a snap.

Comparing Canvas and SVG

Canvas and SVG have a few features in common. Both Canvas and SVG have an Open Source library ecosystem, and you never need plug-ins for either technology. Table 1 is a side-by-side comparison of common Canvas and SVG characteristics.

Canvas SVG
Single DOM element Multiple DOM elements
Script language Markup language
Raster graphics Vector graphics
No file format .svg file format
Must reset canvas to change drawn shape Can edit shapes after drawing
Not accessible Accessible
Doesn’t support event handlers Supports event handlers
Non-searchable, can’t index Searchable, can index
Non-compressible Compressible
Can use hardware acceleration No hardware acceleration

Table 1 Comparison of Canvas and SVG features

Canvas tends to be well suited for highly interactive games, especially when combined with Internet Explorer 9 GPU offloading. Canvas is a great choice for image editing, and although you can’t edit , you can save the context state to allow the user to undo actions, essentially to do real-time editing.

SVG is great for graphic basics such as displaying a resolution-independent company logo that scales to any screen size without pixel distortion. Fractals and Mandelbrot sets are just two types of complex data visualizations that are well suited for SVG.

Summary

Developers must pull some JavaScript and CSS magic tricks out of their hats for anything more than basic graphic manipulation in Web pages (without using plug-ins) unless they are using Canvas. The Canvas API exposes a rich set of methods for raster manipulation and animation.

SVG relies on mathematics to scale perfectly without limits. You can easily edit, search and index SVG since it is just domain-specific XML.

Both Canvas and SVG are part of W3C standards, and most browsers currently support both of these W3C standards. Each technology is flexible enough to cover a wide range of common tasks involving graphic manipulation and animations.


Rachel Appel is a developer evangelist at Microsoft New York City. You can reach her via her Web site athttp://rachelappel.comor by e-mail atrachel.appel@microsoft.com. *You can also follow her latest updates on Twitter at @rachelappel.*