我正在尝试将d3 svg保存为基于this主题的高质量png图像。
问题是我的svg是响应式的,所以它没有宽度和高度属性。结果,最终的png看起来不正确(宽度/高度比不正确)。
我最终尝试使用正确的宽度和高度属性创建一个新的svg元素并继续使用这个元素,但似乎我做错了。
这是我的代码:
var w = 193,
h = 260;
var ratio = 2;
var canvas1 = document.createElement('canvas');
canvas1.id = "canvas1";
canvas1.width = w * 2.0;
canvas1.height = h * 2.0;
document.getElementById('pngcon').appendChild(canvas1);
var svg = document.getElementById(`chartId`).querySelector('svg');
var step = document.createElement('svg');
step.id = 'newsvg';
step.setAttribute('width', w);
step.setAttribute('height', h);
step.innerHTML = $('#SupportingBeamCrossSectionSVG').html();
document.getElementById('cont').appendChild(step);
var html = new XMLSerializer().serializeToString(document.getElementById(`cont`).querySelector('svg'));
var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var canvasdata;
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image, 0, 0, canvas.width, canvas.height);
canvasdata = canvas.toDataURL("image/png");
var a = document.createElement("a");
a.id = "imagepng"
a.innerHTML = "output file, right click - save as since click() won't work in snippet";
a.download = "output.png";
a.href = canvasdata;
document.body.insertBefore(a, document.getElementById(`chartId`));
}
我创建了一个jsfiddle here。
答案 0 :(得分:0)
要创建SVG元素,请执行此操作。
var step = document.createElementNS("http://www.w3.org/2000/svg","svg");
var w = 193,
h = 260;
var ratio = 2
console.log(ratio);
var canvas1 = document.createElement('canvas');
canvas1.id = "canvas1";
canvas1.width = w * ratio;
canvas1.height = h * ratio;
document.getElementById('pngcon').appendChild(canvas1);
var svg = document.getElementById(`chartId`).querySelector('svg');
var step = document.createElementNS("http://www.w3.org/2000/svg","svg");
step.id = 'newsvg';
step.setAttribute('width', w);
step.setAttribute('height', h);
step.innerHTML = $('#SupportingBeamCrossSectionSVG').html();
document.getElementById('cont').appendChild(step);
var html = new XMLSerializer().serializeToString(document.getElementById('cont').querySelector('svg'));
var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var canvasdata;
var image = new Image;
image.src = imgsrc;
console.log(imgsrc);
image.onload = function() {
context.drawImage(image, 0, 0, canvas.width, canvas.height);
canvasdata = canvas.toDataURL("image/png");
var a = document.createElement("a");
a.id = "imagepng"
a.innerHTML = "output file, right click - save as since click() won't work in snippet";
a.download = "output.png";
a.href = canvasdata;
document.body.insertBefore(a, document.getElementById(`chartId`));
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="chartId">
<svg id="SupportingBeamCrossSectionSVG" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xml:space="preserve" viewBox="0 0 193 260" enable-background=" new 0 0 193 260" height="260" width="193" style="max-width: 193px"><path id="SupportingBeamCrossSectionSVG" d="M-36.5,-70 L36.5,-70 L36.5,-63.1 L9.35,-63.1 A7,7 1 0,02.35,-56.1 L2.35,56.1 A7,7 1 0,09.35,63.1 L36.5,63.1 L36.5,70 L-36.5,70 L-36.5,63.1 L-9.35,63.1 A7,7 1 0,0-2.35,56.1 L-2.35,-56.1 A7,7 1 0,0-9.35,-63.1 L-36.5,-63.1 Z" fill="#428bca" transform="translate(96.5, 130)"></path><g fill="#484D61" transform="translate(96.5, 130)"><circle cx="0" cy="0" r="2"></circle><line x1="0" y1="0" x2="96.5" y2="0" stroke="#484D61" stroke-width="1" stroke-dasharray="5,5"></line><line x1="0" y1="0" x2="0" y2="130" stroke="#484D61" stroke-width="1" stroke-dasharray="5,5"></line><polygon points="96.5,0 86.5,4 86.5,-4"></polygon><polygon points="0,130 -4,120 4,120"></polygon><text x="96.5" y="13.5" font-family="Verdana" font-size="10" text-anchor="end">y</text><text x="7.5" y="130" font-family="Verdana" font-size="10" text-anchor="start">z</text></g><g id="hSupportingBeam" fill="#484D61" transform="translate(15, 60)"><g transform="translate(0, 70)"><line x1="0" y1="-75" x2="0" y2="75" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-70" x2="5" y2="-70" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="70" x2="5" y2="70" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-70" r="2" fill="#484D61"></circle><circle cx="0" cy="70" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>140.00<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="tfSupportingBeam" fill="#484D61" transform="translate(40, 193.1)"><g transform="translate(0, 3.45)"><line x1="0" y1="-8.45" x2="0" y2="8.45" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-3.45" x2="5" y2="-3.45" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="3.45" x2="5" y2="3.45" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-3.45" r="2" fill="#484D61"></circle><circle cx="0" cy="3.45" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>6.90<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="heSupportingBeam" fill="#484D61" transform="translate(40, 73.9)"><g transform="translate(0, 56.1)"><line x1="0" y1="-61.1" x2="0" y2="61.1" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-56.1" x2="5" y2="-56.1" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="56.1" x2="5" y2="56.1" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-56.1" r="2" fill="#484D61"></circle><circle cx="0" cy="56.1" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>112.20<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="bSupportingBeam" fill="#484D61" transform="translate(60, 40)"><g transform="translate(36.5, 0)"><line x1="-41.5" y1="0" x2="41.5" y2="0" stroke="#484D61" stroke-width="1"></line><line x1="-36.5" y1="-5" x2="-36.5" y2="5" stroke="#484D61" stroke-width="1"></line><line x1="36.5" y1="-5" x2="36.5" y2="5" stroke="#484D61" stroke-width="1"></line><circle cx="-36.5" cy="0" r="2" fill="#484D61"></circle><circle cx="36.5" cy="0" r="2" fill="#484D61"></circle><text x="0" y="-7.5" font-size="10" font-family="Verdana" text-anchor="middle"><tspan>73.00<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="twSupportingBeam" fill="#484D61" transform="translate(94.15, 172)"><g transform="translate(2.35, 0)"><line x1="-7.35" y1="0" x2="7.35" y2="0" stroke="#484D61" stroke-width="1"></line><line x1="-2.35" y1="-5" x2="-2.35" y2="5" stroke="#484D61" stroke-width="1"></line><line x1="2.35" y1="-5" x2="2.35" y2="5" stroke="#484D61" stroke-width="1"></line><circle cx="-2.35" cy="0" r="2" fill="#484D61"></circle><circle cx="2.35" cy="0" r="2" fill="#484D61"></circle><text x="4.7" y="-7.5" font-size="10" font-family="Verdana" text-anchor="start"><tspan>4.70<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g transform="translate(105.85, 73.9)"><circle cx="-4.949747468305833" cy="-4.949747468305833" r="2" fill="#484D61"></circle><polyline fill="none" stroke="#484D61" points="-9.949747468305834,-9.949747468305834 4.949747468305833,9.949747468305834 39.94974746830583,9.949747468305834"></polyline><text x="22.449747468305834" y="3.4497474683058327" fill="#484D61" font-size="10" font-family="Verdana" text-anchor="middle">7.00</text></g></svg>
</div>
<div id="cont"></div>
<div id="pngcon"></div>
&#13;