我目前正在使用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);
}
答案 0 :(得分:5)
样式表中定义的svg元素的样式定义不会应用于生成的画布。这可以通过在调用canvg之前向svg元素添加样式定义来修补。
受this article的启发,我创造了这个:
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'));
答案 1 :(得分:2)
这里的关键是所有样式规则都需要成为SVG的一部分,而不是外部样式文件。因此,您需要浏览NVD3的所有CSS并在代码中设置所有这些属性。通过外部样式表设置的任何内容都将被忽略。
答案 2 :(得分:0)
让@Lars Kotthoff的答案更加具体。 “example of how to export a png directly from an svg”有一个有效的例子。代码片段/ gist尝试首先将所有css应用于svg内联,然后在画布上绘制图像并将数据导出为png。 (内部采用svg-crowbar代码)。我在我的项目中应用该技术,它运行顺畅 - 一个下载按钮,可以下载使用nvd3呈现的svg图像。