Category Archives: Javascript

Converting SVG to Canvas, with styles, using canvg

Canvg is a utility to convert SVG objects to canvas objects, which can then be further used as images or whatnot.  Trouble is, it only converts the SVG elements, not the CSS applied to it.  So the top SVG becomes the bottom canvas in the conversion.

2018-06-19_9-47-38

Not what was needed.  The issue is that the blue in the SVG isn’t embedded as style tags on the <rect> elements; it’s applied by the browser from the CSS stylesheet.

Luckily, in my project, there are only a handful of CSS rules dealing with the SVG elements.  So the solution was relatively simple.  Insert the styles into the SVG before proceeding. SVG honors a <style> tag.

var svg1 = document.getElementById('svg_item'),
width = svg1.width.baseVal.value,
height = svg1.height.baseVal.value;
$('#canvas').width(width).height(height);
var source = (new XMLSerializer()).serializeToString(d3.select('#svg_item').node());
var styles = '<style type="text/css"> rect { fill: #0048af; } .axis line, .axis path { fill: none; stroke: #000; shap-rendering: crispEdges; }</style>';
var first = source.indexOf('>') +1; // First closing tag
source = source.slice(0, first) + styles + source.slice(first);
canvg('canvas', source);

What this does is inline the styles directly in the SVG string passed to Canvg, before processing it.  Turning the first two tags of the SVG:

<svg xmlns="http://www.w3.org/2000/svg" id="rater_svg_item" width="1000" height="125"><g transform="translate(125, 10)"><rect class="bar" x="0" width="673.11" y="52" height="17"/>

into this:

<svg xmlns="http://www.w3.org/2000/svg" id="rater_svg_item" width="1000" height="125"><style type="text/css"> rect { fill: #0048af; } .axis line, .axis path { fill: none; stroke: #000; shap-rendering: crispEdges; }</style><g transform="translate(125, 10)"><rect class="bar" x="0" width="673.11" y="52" height="17"/>

2018-06-19_10-02-04

Much better.