Tuesday, December 24, 2013

Canvas, SVG or DIV?

A post from stackoverflow.com@http://stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div

Question:

What is the best way for element creation on the fly and being able to move it around? Let's say I want to create rectangle, circle and polygon then I want to select the objects and move it aroundAnd how is the performance of those three while in use for showing a web page? Let's say I want to create three visually identical web page and have header, footer, widget and text content in them. The first one is created using full canvas, the second is created using svg, and the third is created using plain div html and css.

The short answer:

SVG would be easier for you, since selection and moving it around is already built in. SVG objects are DOM objects, so they have "click" handlers, etc.
DIVs are okay but clunky and have awful performance loading at large numbers.
Canvas has the best performance hands-down, but you have to implement all concepts of managed state (object selection, etc) yourself, or use a library.

The long answer:

HTML5 Canvas is simply a drawing surface for a bit-map. You set up to draw (Say with a color and line thickness), draw that thing, and then the Canvas has no knowledge of that thing: It doesn't know where it is or what it is that you've just drawn, it's just pixels. If you want to draw rectangles and have them move around or be selectable then you have to code all of that from scratch, including the code to remember that you drew them.
SVG on the other hand must maintain references to each object that it renders. Every SVG/VML element you create is a real element in the DOM. By default this allows you to keep much better track of the elements you create and makes dealing with things like mouse events easier by default, but it slows down significantly when there are a large number of objects
Those SVG DOM references mean that some of the footwork of dealing with the things you draw is done for you. And SVG is faster when rendering really large objects, but slower when rendering many objects.
A game would probably be faster in Canvas. A huge map program would probably be faster in SVG. If you do want to use Canvas, I have some tutorials on getting movable objects up and running here.
Canvas would be better for faster things and heavy bitmap manipulation (like animation), but will take more code if you want lots of interactivity.
I've run a bunch of numbers on HTML DIV-made drawing versus Canvas-made drawing. I could make a huge post about the benefits of each, but I will give some of the relevant results of my tests to consider for your specific application:
I made Canvas and HTML DIV test pages, both had movable "nodes." Canvas nodes were objects I created and kept track of in Javascript. HTML nodes were movable Divs.
I added 100,000 nodes to each of my two tests. They performed quite differently:
The HTML test tab took forever to load (timed at slightly under 5 minutes, chrome asked to kill the page the first time). Chrome's task manager says that tab is taking up 168MB. It takes up 12-13% CPU time when I am looking at it, 0% when I am not looking.
The Canvas tab loaded in one second and takes up 30MB. It also takes up 13% of CPU time all of the time, regardless of whether or not one is looking at it. (2013 edit: They've mostly fixed that)
Dragging on the HTML page is smoother, which is expected by the design, since the current setup is to redraw EVERYTHING every 30 milliseconds in the Canvas test. There are plenty of optimizations to be had for Canvas for this. (canvas invalidation being the easiest, also clipping regions, selective redrawing, etc.. just depends on how much you feel like implementing)
There is no doubt you could get Canvas to be faster at object manipulation as the divs in that simple test, and of course far faster in the load time. Drawing/loading is faster in Canvas and has far more room for optimizations, too (ie, excluding things that are off-screen is very easy).

Conclusion:

  • SVG is probably better for applications and apps with few items (less than 1000? Depends really)
  • Canvas is better for thousands of objects and careful manipulation, but a lot more code (or a library) is needed to get it off the ground.
  • HTML Divs are clunky and do not scale, making a circle is only possible with rounded corners, making complex shapes is possible but involves hundreds of tiny tiny pixel-wide divs. Madness ensues.

Another Version

Original post: http://www.htmlgoodies.com/html5/other/html5-canvas-vs.-svg-choose-the-best-tool-for-the-job.html#fbid=UApUMpi6eb9

The canvas itself is an HTML element that you can place anywhere in your page, just as with most other elements. The drawing part is accomplished using either a 2D or 3D (WebGL) drawing context. Right now we'll focus on 2D because it has much more browser support, with 3D being still in its infancy. Here's some code that displays a JPEG image in grayscale:
<script type="text/javascript">  
  window.onload = function(){
      //try and create a canvas element
      var testCanvas  = document.createElement('canvas'); 
       
      //check if object supports getContext() method  
      if (testCanvas.getContext !== undefined) {
        var canvas = document.getElementById("effectsCanvas");
        var context = canvas.getContext("2d");
        
        canvas.style.border = "2px solid blue";
        
        var destX = 0;
        var destY = 0;
        var imageObj = new Image();
     
        imageObj.onload = function(){
            context.drawImage(imageObj, destX, destY);
            var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
         var pixels  = imgData.data;
         for (var i = 0, n = pixels.length; i < n; i += 4) {
             var grayscale = pixels[i  ] * .3 + pixels[i+1] * .59 + pixels[i+2] * .11;
             pixels[i  ] = grayscale;  // red
             pixels[i+1] = grayscale;  // green
             pixels[i+2] = grayscale;  // blue
             // alpha
         }
         context.putImageData(imgData, 0, 0);
        };
        imageObj.src = "Rob_at_Greenfields.jpg";
      }
      else {
        document.writeln('You are plum outta luck, cuz your browser does not support the canvas element.');
      }
  }; 
</script> 
</head>
<body>
<h1>HTML5 Canvas Effects Demo</h1>
<canvas id="effectsCanvas" width="500" height="550" > </canvas>  

SVG
The following example creates an oval with a linear gradient using SVG:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>


Comparing the Differences

SVG Is Vector-based, Canvas Manipulates Pixels
What's the difference, you ask? Remember those old vector video games like asteroids and Tempest. No? OK, I'm getting up there! Anyway, those were based on bright line drawings. One of the reasons for their popularity was that they looked quite different from typical games at the time. With regards to SVG and Canvas, the differences are a lot less dramatic visually, as you can load bitmaps in SVG, and you can draw lines using the canvas API. However, creating the image may be easier using one technology over the other, depending on whether your graphic is mainly line-based or more image-like.

SVG Relies on Files, Canvas Uses Pure Scripting
SVG images are defined in XML. As a result, every SVG element is appended to the Document Object Model (DOM) and can be manipulated using a combination of JavaScript and CSS. Moreover, you can attach an event handlers to a SVG element or update its properties based on another document event. Canvas, on the other hand, is a simple graphics API. It draws pixels (extremely well I might add) and nothing more. Hence, there's no way to alter existing drawings or react to events. If you want to update the Canvas image, you have to redraw it.

Other Considerations
SVGs are considered to be more accessible because they support text. In the event that the browser does not support SVG, text content will still be displayed. The Canvas is dependent on JavaScript, so there can be an issue if the user has disabled JavaScript or uses an assistive device such as a reader that cannot interpret the JavaScript output. However, that can be remedied by including the <NOSCRIPT> tag. If you want to present the best user experience for those with JavaScript turned off, SVG would be your best choice.
For front-end designers, there's no question that SVG would be easier to configure, due to XML's high readability. This is the same reason that Frameworks like Spring have been so popular these last few years; pretty much anyone can use them. Canvas images are created programmatically and require some programming expertise that is more suited to a developer.
 
Conclusion
I've tried to provide some options here that you can hopefully apply to your own skillset and predispositions. There is no black and white answer to be found, so you'll have to weigh your options before committing to any one technology. Consider that SVG will result in slower rendering as document complexity increases due to SVG's integration into the DOM. Hence, SVG would probably not be best for dynamic applications like games. Downsides of the Canvas include poor text rendering capability, lack of animation, as well as mediocre accessibility support. The best advice I can give you is to choose the one that not only best fits the task at hand, but your own comfort level as well.


A 3rd Version

Original post: http://www.sitepoint.com/canvas-vs-svg-how-to-choose/ 
At first glance, canvas and SVG appear to be different techniques that achieve the same thing. Both permit graphic manipulation in the browser, and either could be a solution for some projects. However, there are several subtle differences between the two, and choosing the wrong technology could cause development headaches later on.

Vectors vs Pixels

The primary difference between the two formats is that SVG is vector based, whereas canvas offers pixel operations.
The distinction is somewhat blurred — you can load bitmaps in SVG, and the canvas API can draw lines and shapes. But the final result is what’s important: SVGs remain as vectors but canvas elements are bitmaps. You can draw a shape on the surface of a canvas element, but it will become a collection of pixels.

Document vs Script

SVG images are defined in XML. An image can be created on the server side, or within a package such as Inkscape, and loaded directly into the browser for viewing and client-side manipulation.
Canvas is script-based and cannot operate when JavaScript’s disabled. All canvas images are built using a series of API drawing commands.

Objects vs Graphics

Every SVG element becomes part of the DOM and can be manipulated accordingly. For example, you can attach an “onclick” event handler to a shape, or examine its properties using a tool such as Firebug. Although this is useful, there is a performance hit when you’re working with large numbers of objects.
Canvas is a low-level graphics API. You’re drawing pixels — it’s very fast, but it’s not possible to manipulate existing shapes or attach event handlers.

Accessibility vs Alternative Content

SVGs are accessible: text remains as text, and something should appear even when the browser does not support SVG.
Canvas elements depend on JavaScript: if that’s not available, the browser will need to show alternative content.

Designer vs Developer

Many vector graphics packages already support the SVG format, so it’s easy for a designer to create an image and use it immediately.
Canvas images are built programmatically and require a developer to implement the code. I suspect canvas creation tools will appear, but programming knowledge will always be necessary.

Browser Support

Firefox, Chrome, Safari and Opera support both technologies, and Microsoft has announced that canvas and SVGwill be available in Internet Explorer 9. Unfortunately, IE9 isn’t expected until next year and it won’t be available on XP — many users will remain on IE8 or below for years to come.
At the time of writing, SVG is probably the most viable cross-browser solution. There are several IE SVG plugins, and libraries such as Raphaël utilize IE’s native VML support.

Which Should You Choose?

In general, SVG is best suited to scalable and interactive graphics. Canvas is the best option for fast games or animations where hundreds of elements are being rendered. There will be situations where either format could be used, such as data charts.
More cautious developers will probably avoid SVG and canvas until a large majority of users have one or both enabled. However, they are viable technologies and there’s little reason why you shouldn’t investigate them further. They’re certainly an option for progressive enhancement techniques — for example, IE8 and earlier versions show a table of data whereas supported browsers show an animated pie chart.
Are you using SVG or canvas within your projects, or is it too early to adopt these technologies?

No comments:

Post a Comment