Displaying SVG images in canvas

A script to use predefined shapes (described in SVG) in an HTML 5 canvas surface.

It would be interesting to have a library of images to canvas, not just sprites, but also vector images which we can change the size or modify the components, or replace them to produce new images.

Using SVG, we have a way to describe these images in a simple and standard way.

The script that has been created for display them does not support files made with software such as Inkscape, which uses SVG as a storage format, but is not designed to optimize the SVG code. Your images should be written in source code, but a software as SVG Edit can also provide a true SVG code.

A tool is included in the archive to convert svg images in JavaScript objects. Then the SVGtoCanvas function displays the object in a canvas tag at an incomparably higher speed than that of SVG display.

Example of use

SVG

Scriptol

Source code of the image:

<svg id="car"  xmlns="http://www.w3.org/2000/svg"  width="400" height="200">
<g stroke="#000000" stroke-width="2" fillStyle="none">
<!-- Bodywork -->
<line x1="50" y1="40" x2="100" y2="40" />
<line x1="45" y1="35" x2="50" y2="40" />
<line x1="100" y1="40" x2="105" y2="35" />
<line x1="105" y1="35" x2="140" y2="35" />
<line x1="105" y1="35" x2="100" y2="15" />
<line x1="40" y1="60" x2="140" y2="60" />
<!-- Radiator -->
<rect x="140" y="35" width="5" height="25" fill="none" stroke-width="2" />
<!-- Wheels -->
<ellipse cx="30" cy="60" rx="15" ry="15" fill="black" />
<ellipse cx="30" cy="60" rx="12" ry="12" fill="white" />
<ellipse cx="30" cy="60" rx="4" ry="4" fill="gray" stroke-width="1" />
<ellipse cx="140" cy="60" rx="15" ry="15" fill="black" />
<ellipse cx="140" cy="60" rx="12" ry="12" fill="white" />
<ellipse cx="140" cy="60" rx="4" ry="4" fill="gray" stroke-width="1"/>
<!-- Trunk -->
<path d="M 45,35 C 35,35 20,35 10,50" fill="none"/>
<line x1="10" y1="50" x2="15" y2="60" />
<!-- Hood -->
<path d="M 45,35 C 30,10 35,10 100,15" fill="none" stroke-width="2"/>
<path d="M 55,40 C 50,15 35,15 100,15" fill="none" stroke-width="2"/>
<!-- Glass separator-->
<line x1="75" y1="40" x2="70" y2="15" />
<!-- Ad -->
<text x="60" y="53" font-size="14">Scriptol</text>
</g>
</svg>

Canvas

JavaScript source code:

<canvas id="solcar" width="400" height="100"></canvas>

<script src="code/scriptolcanvas.js"></script>
<script src="car.js"></script>

<script>
 var ctx = canvasInit("solcar")
SVGtoCanvas(car, ctx, 0, 0) </script>

Previously we produced the car.js file from car.svg with the svgtojs.js script

How the image is displayed in the canvas tag

Here is the source code of the SVGtoCanvas function:

function SVGtoCanvas(el, ctx, xo, yo) {
    var tag 
    var x, x2, y, y2, cx, cy, rx, ry, w, h
    var data, font, arr, path
    var fillFlag=false
    ctx.save()  
    ctx.beginPath()  
    for(var att in el) {
       var val = el[att]
       switch(att) {
       case 'tag':
            tag = val
            break
       case 'data':
            data = val            
       case 'stroke':
            ctx.strokeStyle=val
            break
       case 'stroke-width':
            ctx.lineWidth=val
            break
       case 'fillStyle':
       case 'fill':
            if(val=="none") val="transparent"
            ctx.fillStyle=val
            fillFlag=true
            break                
       case 'x':
       case 'x1':
            x = Number(val) + xo
            break
      ... etc...
      } 
    }
    switch(tag) {
        case 'line':
            ctx.moveTo(x,y)
            ctx.lineTo(x2,y2)
            ctx.stroke()
            break;
        case 'circle':
            ctx.arc(cx, cy, rx, 0, 2 * Math.PI);
            ctx.stroke();                
            break;
       ... etc...
   }
   ctx.restore()        
}

The full code is in the archive to download.
All compilers know how to optimize switch ... case structures, so that displaying such image is extremely fast.

The canvas API commands are not all yet implemented, which is why the code is posted on GitHub: it is easy to complete it if needed and share the changes.