SVG2PNG

by Léo Durand

HTML

<script>
  function saveImage() {
var svg = document.querySelector('svg');
var doSomethingWith = function(canvas) {
  document.body.appendChild(canvas)
};



var parseStyles = function() {
  var styleSheets = [],
    i;
  // get the stylesheets of the document (ownerDocument in case svg is in <iframe> or <object>)
  var docStyles = svg.ownerDocument.styleSheets;
  // transform the live StyleSheetList to an array to avoid endless loop
  for (i = 0; i < docStyles.length; i++) {
    styleSheets.push(docStyles[i]);
  }
  if (styleSheets.length) {
    // getDef() will return an svg <defs> element if already into the node, or will create it otherwise
    getDef();
    svg.matches = svg.matches || svg.webkitMatchesSelector || svg.mozMatchesSelector || svg.msMatchesSelector || svg.oMatchesSelector;
  }

  // iterate through all document's stylesheets
  for (i = 0; i < styleSheets.length; i++) {
    // create a new style element
    var style = document.createElement('style');
    // some stylesheets can't be accessed and will throw a security error
    try {
      var rules = styleSheets[i].cssRules,
        l = rules.length;
      // iterate through each cssRules of this stylesheet
      for (var j = 0; j < l; j++) {
        // get the selector of this cssRules
        var selector = rules[j].selectorText;
        // is it our svg node or one of its children ?
        if ((svg.matches && svg.matches(selector)) || svg.querySelector(selector)) {
          // append it to our <style> node
          style.innerHTML += rules[j].cssText + '\n';
        }
      }
      // if we got some rules
      if (style.innerHTML) {
        // append the style node to the clone's defs
        defs.appendChild(style);
      }
    } catch (e) {
      console.warn('unable to get some cssRules : ', e);
    }
  }
  // small hack to avoid border and margins being applied inside the <img>
  var s = svg.style;
  s.border = s.padding = s.margin = 0;
  s.transform = 'initial';
 ...

CSS

rect {
          fill: red;
          stroke-width: 5;
          stroke-linejoin: round;
          padding: 25em;
          border: 25px solid yellow;
        }
        
        canvas {
          border: 1px solid green;
        }
        
        svg {}
        
        #box {
          width: 100px;
          height: 100px;
        }
        
        #frame_svg {
          left: 10vw;
          top: 10vh;
          width: 30vw;
          height: 30vh;
        }
        
        .svg {
          fill: none;
          stroke: #333333;
          stroke-width: 10;
          vector-effect: non-scaling-stroke;
          stroke-linejoin: round;
          stroke-linecap: round;
        }