Конвертирайте SVG в PNG и поддържайте целостта на CSS

В момента използвам canvg() и Canvas2Image, за да копирам моя SVG в платно и след това да конвертирам платното в PNG. Бих искал да запазя формата на изображението и да не използвам PDF.

Как мога да поддържам целостта на CSS? Диаграмата е направена с помощта на NVD3.js.

downloadPhoto: function() {
  var chartArea = document.getElementsByTagName('svg')[0].parentNode;
  var svg = chartArea.innerHTML;
  var canvas = document.createElement('canvas');
  canvas.setAttribute('width', chartArea.offsetWidth);
  canvas.setAttribute('height', chartArea.offsetHeight);
  canvas.setAttribute('display', 'none');

  canvas.setAttribute(
    'style',
    'position: absolute; ' +
    'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
    'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
  document.body.appendChild(canvas);
  canvg(canvas, svg);
  Canvas2Image.saveAsPNG(canvas);
  canvas.parentNode.removeChild(canvas);
}

Оригинален SVG

SVG преобразуван в PNG


person collenjones    schedule 05.12.2013    source източник


Отговори (3)


Стиловите дефиниции за svg елементи, дефинирани в таблици със стилове, не се прилагат към генерираното платно. Това може да бъде коригирано чрез добавяне на стилови дефиниции към svg елементите, преди да извикате canvg.

Вдъхновен от тази статия, създадох това :

function generateStyleDefs(svgDomElement) {
  var styleDefs = "";
  var sheets = document.styleSheets;
  for (var i = 0; i < sheets.length; i++) {
    var rules = sheets[i].cssRules;
    for (var j = 0; j < rules.length; j++) {
      var rule = rules[j];
      if (rule.style) {
        var selectorText = rule.selectorText;
        var elems = svgDomElement.querySelectorAll(selectorText);

        if (elems.length) {
          styleDefs += selectorText + " { " + rule.style.cssText + " }\n";
        }
      }
    }
  }

  var s = document.createElement('style');
  s.setAttribute('type', 'text/css');
  s.innerHTML = "<![CDATA[\n" + styleDefs + "\n]]>";
  //somehow cdata section doesn't always work; you could use this instead:
  //s.innerHTML = styleDefs;

  var defs = document.createElement('defs');
  defs.appendChild(s);
  svgDomElement.insertBefore(defs, svgDomElement.firstChild);
}

// generate style definitions on the svg element(s)
generateStyleDefs(document.getElementById('svgElementId'));
person R. Oosterholt    schedule 11.08.2015

Ключовото тук е, че всички стилови правила трябва да са част от SVG, а не във външни стилови файлове. Така че ще трябва да преминете през целия CSS за NVD3 и да зададете всички тези атрибути в кода. Всичко, което е зададено чрез външен стилов лист, ще бъде игнорирано.

person Lars Kotthoff    schedule 05.12.2013

само за да направя отговора на @Lars Kotthoff по-конкретен. „пример за това как да експортирате png директно от svg“ има работещ пример. кодовият фрагмент/gist се опитва първо да приложи всички css към вградения svg и след това да начертае изображението върху платното и да експортира данните като png. (вътрешно той прие svg-crowbar код). и прилагам техниката в моя проект и тя работи гладко - бутон за изтегляне, който може да изтегли svg изображението, изобразено чрез nvd3 .

person Dyno Fu    schedule 31.12.2016