SVG to Canvas


Sometimes it’s necessarily to have all the object on a canvas element instead on a SVG element, but we still want to benefit from SVG features like precise collision detection. It is possible to animate the SVG element and draw on each frame onto the canvas, or animate an element on the canvas itself based on SVG data. It is also possible to convert a canvas element to SVG.

 

SVG to canvas

To convert an SVG element to a canvas element we use the canvg library. Which parses the SVG element and draws it onto canvas. This is done by just a few lines of additional code.

    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
function renderCanvas()
{
    var oSerializer = new XMLSerializer();
    var sXML = oSerializer.serializeToString(document.getElementById("SVG_scene"));

    canvg(document.getElementById('canvas'), sXML,{ ignoreMouse: true, ignoreAnimation: true })
}

First we need plane xml text to parse onto a canvas element. This is done by an XMLSerializer(), we just take the SVG object and create an XML file out of it. Once the XML is ready we draw it onto the canvas with the canvg() function. You could convert SVG native Mouse or Animation data as well, but its not necessarily in this case.
Each change on the SVG object needs to be parsed to an XML file to keep the canvas up to date. In this case we call the renderCanvas() function in the renderTick, to update the canvas on each frame.

 

canvas to SVG

It’s also possible to draw the content of a canvas element onto an SVG element. This is done by creating an image out of the canvas and draw it onto an SVG element. This will result in an image on the SVG element whitout any SVG specific objects like path, square, circle, etc.

 While animating, we are creating each frame a new object, this will slow down render time drastically.

//CREATE IMAGE DATA FROM CANVAS ELEMENT
    var img_dataurl = document.getElementById('canvas').toDataURL("image/png");

    //CREATE A SVG ELEMENT
    var svg_img = document.createElementNS("http://www.w3.org/2000/svg", "image");
        svg_img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", img_dataurl); //CREATE SVG IMAGE OBJECT
        svg_img.setAttributeNS(null,"width",document.getElementById("svgWrapper").offsetWidth); //CENTER OF THE CIRCLE Y
        svg_img.setAttributeNS(null,"height",document.getElementById("svgWrapper").offsetHeight); //CENTER OF THE CIRCLE Y

    //APPEND SVG ELEMENT
    svg.appendChild(svg_img);

We create an image out of the canvas by using the toDataURL() function, which parses the canvas element to imageData. Once the image is parsed we create an new SVG image element on which we can draw the parsed image.

To animate this now, we call the function on each frame. This will remove the old SVG image and add the new updated one. Add and remove SVG objects on each frame will cause huge performance issues.

 

conclusion

From SVG to canvas seems to work fine and without any additional work, even visa versa. The canvg library does the job very well, and there are multiple different parameters that can be set within.