์๋ ํ์ธ์,
html2canvas๋ SVG ์บก์ฒ๋ฅผ ์ง์ํฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒํด์ผํฉ๋๊น? ์๋ฅผ ๋ค์ด ์ฃผ์๊ฒ ์ต๋๊น?
ํ ์คํธ ์ด๋ฏธ์ง์ ์์ ๋ SVG๋ฅผ ์บก์ฒํ์ง ์์์ต๋๋ค.
๋์์ฃผ์ธ์. ๊ฐ์ฌํฉ๋๋ค.
์๋ ๊ทธ๋ ์ง ์์. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฒฐํจ์ ์๋์ง๋ง ๋๋ถ๋ถ์ ๋ธ๋ผ์ฐ์ ์ ๋ฒ๊ทธ์
๋๋ค (์ต์ ์์ ์ ์ธ Firefox ๋ฒ์ 12์์๋์ด ๋ฌธ์ ๊ฐ ์์ ๋์์ผ๋ฉฐ ์์๋๋ก ์๋ํ๋ ์ ์ผํ ๋ฌธ์ ์
๋๋ค). ๋ฌธ์ ๋ ๋ชจ๋ SVG ์ด๋ฏธ์ง๊ฐ ์บ๋ฒ์ค๋ฅผ ์ค์ผ์์ผ ์ฝ์ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก html2canvas๋ ์บ๋ฒ์ค๋ฅผ ์ฝ๊ธฐ ์ฝ๊ฒ ์ ์งํ๊ธฐ ์ํด ์ด๋ฏธ์ง๋ฅผ ์ค์ผ์ํค๋ ์ฝํ
์ธ ๋ฅผ ๋ฌด์ํฉ๋๋ค (์ : toDataUrl
๋ฅผ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ).
๊ทธ๋ฌ๋, ๋น์ ์ SVG ์ด๋ฏธ์ง๊ฐ ์บ๋ฒ์ค ๋๋ฌ์ด ๊ฒ์ ๊ฑฑ์ ํ์ง ์๋ ๊ฒฝ์ฐ์, ๋น์ ์ ์ต์
์ ์ค์ ํ ์ ์์ต๋๋ค allowTaint
์ true
ํ๊ณ SVG์ ์ธ๋ผ์ธ SVG๋ฅผ ํ์ฉ ๋ธ๋ผ์ฐ์ ์์ ์ ๋๋ก ๋ ๋๋งํ๋ค.
๋ํ SVG ๋ ๋๋ง์ด ๋ธ๋ผ์ฐ์ ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ฉด SVG๋ฅผ ์ฌ์ฉํ์ฌ HTML์ ๋ ๋๋ง ํ ์ ์์ผ๋ฏ๋ก์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ฑฐ์ ์ธ๋ชจ ์๊ฒ ๋ ๊ฒ์ ๋๋ค. SVG ๋ ๋๋ง์ด ์๋ํ๋ ๋ธ๋ผ์ฐ์ (์ : FF12)์์ ์บ๋ฒ์ค ๋ ๋๋ง์ ํฌ๊ฒ ๊ฐ์ํํ๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ํ๋ ๋ชจ๋ CSS ์์ฑ์ ๋ํ ์ง์์ ํ์ฉํ๋ ์ผ๋ถ ์ฝ๋๋ฅผ ์ด๋ฏธ ์์ฑํ์ต๋๋ค. ์์ธํ ๋ด์ฉ์ https://github.com/niklasvh/html2canvas/blob/master/src/Parse.js#L1227 ์
์๋
ํ์ธ์,
๋น ๋ฅธ ๋ต๋ณ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
๋๋ ๋น์ ์ ์ ์์ผ๋ก ์๋ํ์ต๋๋ค : allowTaint๋ฅผ ์๋์ ๊ฐ์ด true๋ก ์ค์ ํ์ญ์์ค (test.js ์์ ).
setTimeout (function () {
$(h2cSelector).html2canvas($.extend({
flashcanvas: "../external/flashcanvas.min.js",
logging: true,
profile: true,
useCORS: true,
allowTaint: true
}, h2cOptions));
}, 100);
example images.html์์ SVG๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๋ ๋๋งํฉ๋๋ค.
๊ทธ๋ฌ๋ SVG๊ฐ ๋ ๋ณต์กํ ๊ฒฝ์ฐ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ์์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ์ : Chrome์์ ์ฐจํธ (http://www.highcharts.com/demo/)๋ฅผ ์บก์ฒํ๊ณ ์ถ์ต๋๋ค. ์ฐจํธ๊ฐ ์ธ๋ผ์ธ SVG๋ก ๋ ๋๋ง ๋ ๋ ์ฐจํธ์ x ์ถ๊ณผ y ์ถ๋ง ์บก์ฒํฉ๋๋ค. extenal svg ํ์ผ์ ์์ค๋ฅผ ์ฌ์ฉํ์ฌ img๋ก ๋ ๋๋งํ๋ฉด ์๋ฌด๊ฒ๋ ์บก์ฒํ์ง ์์ต๋๋ค.
๋ฐ๋๋ก Chrome์ Firefox์์ ์ฐจํธ๊ฐ ์ธ๋ผ์ธ SVG๋ก ๋ ๋๋ง ๋ ๋ ์๋ฌด๊ฒ๋ ์บก์ฒํ์ง ์์ง๋ง ์ฐจํธ๊ฐ ์ธ๋ถ svg ํ์ผ์ ์ด๋ฏธ์ง ์ผ ๋ ์ฑ๊ณต์ ์ผ๋ก ์ฐจํธ๋ฅผ ์บก์ฒ ํ ์ ์์ต๋๋ค. ์ต์
์ ๊ฒฝ์ฐ๋ IE9์ด๋ฉฐ ์๋ฌด๊ฒ๋ ์บก์ฒ๋์ง ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์์ด๋์ด๊ฐ ์์ต๋๊น?
์ด๋ฏธ์ง๋ก ์ฌ์ฉํ๋ฉด FF / Chrome์์ ์๋ํฉ๋๋ค. ์๋ํด ๋ณผ ์์๋ ๊ฒ์ drawImage๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋จํ ์บ๋ฒ์ค ๋ ๋๋ง์ด SVG์ ํจ๊ป ์๋ํ๋์ง ์ฌ๋ถ์ ๋๋ค.
์ด๊ฒ์ ๋ํด +1. babyhero์ ๋์ผํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค.๋ณด๊ณ ๋๊ตฌ๋ฅผ ์ํด highcharts SVG ๊ทธ๋ํ์ ์คํฌ๋ฆฐ ์ท์ ์บก์ฒํด์ผํฉ๋๋ค. ๋ชจ๋ ํ์ด ์ฐจํธ SVG๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ๊ฐ์ ธ ์ค๋ ๊ฒ์ด ๊ฐ๋ฅํ ์ ์์ง๋ง "์คํฌ๋ฆฐ ์ท์ ์ ์ฅ"๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ ๋ค๋ฅธ ์ ๋ณด๊ฐ ํฌํจ ๋ ๋ทฐ ๋ด์์ ๋ ๋๋ง๋ฉ๋๋ค.
@ babyhero184 canvg (http://code.google.com/p/canvg/)๋ฅผ ์ฌ์ฉํ์ฌ highcharts SVG๋ฅผ PNG๋ก ์ฆ์ ๋ณํํ๊ณ SVG ์์๋ฅผ ์จ๊ธฐ๊ณ PNG๋ฅผ ํ์ํ์ฌ html2canvas์์์ด ์ ํ์ ๊ทน๋ณตํ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ html2canvas๋ก ์ฆ์์์ ์คํฌ๋ฆฐ ์ท์ ์ฐ๊ณ PNG๋ฅผ ์จ๊ธฐ๊ณ ํ์ด ์ฐจํธ SVG๋ฅผ ๋ค์ ๋ณด์ฌ์ฃผ์์ต๋๋ค. ๋กํฐ๋ฆฌ ํ๋ก์ธ์ค (SVG-> ์บ๋ฒ์ค-> PNG-> ์บ๋ฒ์ค-> PNG)์ด์ง๋ง ๋ด ํ์์ ๋ฐ๋ผ ์๋ํฉ๋๋ค.
@joeyrobert ๋๋ ๋ํ highcharts์ html2canvas์์ ๊ฐ์ ๋ฌธ์ ์ ์ง๋ฉดํ๊ณ ์์ต๋๋ค. ์ฝ๋์ ์์ง๋ฅผ ๊ณต์ ํ ์ ์๋ค๋ฉด ํฐ ๋์์ด ๋ ๊ฒ์
๋๋ค.
๋ฏธ๋ฆฌ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
@joeyrobert @ Jagdeep1 ๋ ๋ค๋ฅธ ์ต์ ์ Fabric.js ๋ฅผ ์ฌ์ฉํ์ฌ ์บ๋ฒ์ค์ SVG๋ฅผ ๋ ๋๋ง ํ ๋ค์ ์ด๋ฏธ์ง๋ฅผ ๊ฒ์ํ๋ ๊ฒ์ ๋๋ค.
+1
+1
+1
์ด ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ด ์์ต๋๊น?
@majuansari _SVG_ to _Canvas_ ๋ฐ _Canvas_ to _image_๋ firefox์์ ์๋ํ์ง๋ง Chrome์๋ ๋ณด์ ์ ๊ธ์ด ์์ต๋๋ค.
์ฐจํธ ์์๋ฅผ ์บก์ฒํ๊ธฐ ์ํด jQuery๋ฅผ ์ฌ์ฉํ๊ณ ์์๋๋ฐ ๊ทธ๋ ๊ฒํ์ ๋ Highcharts SVG๊ฐ ์ ๋๋ก ๊ตฌ๋ฌธ ๋ถ์๋์ง ์์ ์์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๋๊ตฐ๊ฐ ์ฐจํธ์ jQuery ์ ํ๊ธฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒฝ์ฐ SVG๊ฐ ํฌํจ๋์ง ์์ ์ ์์ต๋๋ค.
@mbritton http://code.google.com/p/canvg/ ์๋ (foreignObject๊ฐ ์๋ํ์ง ์์)
์, ๊ทธ๊ฒ์ด ์ ํด๊ฒฐ์ฑ ์ด์์ต๋๋ค.
์บก์ฒํ๋ ๋์ svg ์์๋ฅผ canvg ์์ฑ ์บ๋ฒ์ค ์์๋ก ๋์ฒดํ์ฌ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
๋ค์์ ๋ด ์ฝ๋์
๋๋ค.
// targetElem is a jquery obj
function take (targetElem) {
var nodesToRecover = [];
var nodesToRemove = [];
var svgElem = targetElem.find('svg');
svgElem.each(function(index, node) {
var parentNode = node.parentNode;
var svg = parentNode.innerHTML;
var canvas = document.createElement('canvas');
canvg(canvas, svg);
nodesToRecover.push({
parent: parentNode,
child: node
});
parentNode.removeChild(node);
nodesToRemove.push({
parent: parentNode,
child: canvas
});
parentNode.appendChild(canvas);
});
html2canvas(targetElem, {
onrendered: function(canvas) {
var ctx = canvas.getContext('2d');
ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
canvas.toBlob(function(blob) {
nodesToRemove.forEach(function(pair) {
pair.parent.removeChild(pair.child);
});
nodesToRecover.forEach(function(pair) {
pair.parent.appendChild(pair.child);
});
saveAs(blob, 'screenshot_'+ moment().format('YYYYMMDD_HHmmss')+'.png');
});
}
});
}
์ฐธ๊ณ :
canvg๊ฐ ์ ๋๋ก ์๋ํ๊ณ ์๋ค๊ณ ํ์ ํ์ง๋ง SVG๋ฅผ ์บ๋ฒ์ค๋ก ๋ณํํ๋ ค๋ ๊ฒฝ์ฐ ์ฌ๊ธฐ ์ ์ค๋ช
๋ ๊ฐ๋จํ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง์ svg๋ฅผ๋ก๋ ํ ๋ค์ ์ด๋ฏธ์ง ์ฝํ
์ธ ๋ฅผ dataURL๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
var image = new Image();
var xml = '<svg xmlns=....></svg>';
image.src = 'data:image/svg+xml,' + escape(xml);
document.getElementById('container').appendChild(image);
image.onload = function() {
image.onload = function() {};
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
image.src = canvas.toDataURL();
}
@steren : ์ด๊ฒ์ Chrome์์ ์ ์๋ํ์ง๋ง Firefox์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด
@gifarangw ์ฝ๋๋ highcharts์์ ์ ์๋ํฉ๋๋ค. ๋ฉ์ง ์ฝ๋์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. : +1 : ๋ด๊ฐ ์ ๊ฑฐํ ์ ์ผํ ๊ฒ์ canvas.toBlob ๋ถ๋ถ์ด์์ต๋๋ค.
@steren ์๋ฃจ์ ์ ๊ฐ์ฌ ๋๋ฆฌ๋ฉฐ ์ ์๋ํ๋ฉฐ (์ต์ ํฌ๋กฌ ๋ฐ ํ์ด์ด ํญ์ค์์ ํ ์คํธ ๋จ) ์ข์ ์ถ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๋ช ๊ฐ์ง๋ฅผ ๋ณ๊ฒฝํ๊ณ @gifarangw ์ ์ฝ๋์ ๊ฒฐํฉํ์ฌ ๋ค์์ ์ป์์ต๋๋ค.
function take(targetElem) {
// First render all SVGs to canvases
var elements = targetElem.find('svg').map(function() {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title="hide\/show"/g, "");
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
return {
svg: svg,
canvas: canvas
};
});
targetElem.imagesLoaded(function() {
// At this point the container has no SVG, it only has HTML and Canvases.
html2canvas(targetElem[0], {
onrendered: function(canvas) {
// Put the SVGs back in place
elements.each(function() {
this.canvas.replaceWith(this.svg);
});
// Do something with the canvas, for example put it at the bottom
$(canvas).appendTo('body');
}
})
})
}
(https://github.com/desandro/imagesloaded ์ฌ์ฉ)
์๋ ํ์ธ์, @Remiremi ์๋ฃจ์ ์ด ์ ์๊ฒ ์
@Remiremi @fbotti , ์ด๋ค ์ด์ ๋ก ๋
amcharts์ ํจ๊ป ์ผํ๊ณ ์์ต๋๋ค. ์ด๋ค ์๊ฐ?
@guypaskar ๊ทํ์ svg๋ฅผ ์ถ๊ฐ๋ก ํ๋ ์ดํ
ํด์ผ ํ ์ ์์ต๋๋ค. ๋น์ ์ ์ถ๊ฐ ํ ์ ์์ต๋๋ค $(image).appendTo('body');
์ต์ ์น๋ฅผํ๊ธฐ ์ ์ ์ฝ๋์ image.onload
, ๋ค์ ํ์ด์ด ํญ์ค์์ ๋น์ ์ด ์๋ชป๋ ์ด๋ฏธ์ง์ ๋ํ ์์ด์ฝ์ด ํ์๋ฉ๋๋ค, ๋น์ ์ ๋ฐ๋ก>๋ณด๊ธฐ ์ด๋ฏธ์ง๋ฅผ ํด๋ฆญํ๊ณ ์ค๋ฅ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
amcharts svg์ ๋น ๋ฅด๊ฒ ์๋ํด ๋ณด์๊ณ ์๋ํ๋๋กํ๋ ค๋ฉด svg ํ๊ทธ์ xmlns="http://www.w3.org/2000/svg" width="1400" height="500"
์์ฑ์ ์ถ๊ฐํด์ผํ์ต๋๋ค. (๋์ด์ ๋๋น๋ CSS ์์ฑ์ผ๋ก ์ง์ ๋์์ง๋ง ์ด๋ค ์ด์ ๋ก ์ ํ๋์ง ์์์ต๋๋ค.)
๊ฐ๋จํ ํด๊ฒฐ์ฑ ์ ์ฐพ์์ต๋๋ค.
svg ์ด๋ฏธ์ง์ ๋๋น์ ๋์ด๊ฐ ์๋์ง ํ์ธํ์ญ์์ค.
SVG๋ ์ด๋ฏธ์ง์ฒ๋ผ ์ธก์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ถฉ๋ถํ ์ธ์๊ฐ ์์ต๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ๋๊ตฐ๊ฐ๊ฐ ์์ฝ ํ ์ ์์ต๋๊น? ์๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ ๋์์ต๋๊น? ์ฌ๊ธฐ์ ์ธ๊ธ ๋ ๋๋ถ๋ถ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํจ ํน์ ๋ธ๋ผ์ฐ์ ๋ฌธ์ ๊ฐ 2012 ๋ ์ดํ๋ก ์์ ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฌ๊ธฐ์ ์ผ๋ถ ์๊ฒฌ์ ๋ฐ๋ฅด๋ฉด canvg์ ๊ฐ์ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ ์ด์ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๊น?
๋๋จธ์ง ๋ฌธ์ ์ ๋ํด์๋ # 197 ๋ฐ / ๋๋ # 267์ด ์ ์ฉ๋ฉ๋๊น? ์ด๊ฑด ๋ซ์ ์ ์๋์?
์ ์ด๋ ์ผ๋ถ ๋ธ๋ผ์ฐ์ ์์๋ ์ฌ์ ํ ๋ฌธ์ ์ ๋๋ค.
0.5๋ SVG์ ๋ํ ์ง์์ ์ถ๊ฐํฉ๋๋ค.
0.5๊ฐ @niklasvh๋ก ๋์ฌ ๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ ์์ต๋๊น?
@IvoPereira # 421์์ 0.5์ ์ํ๋ฅผ ๋ฐ๋ฅผ ์ ์์ต๋๋ค.
@niklasvh ๋ฒ์ 0.5๊ฐ ์๊ณ SVG๋ ์ฌ์ ํ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์๊ฐ ์์ต๋๊น? (์ธ๋ผ์ธ SVG)
@nikolang html2canvas.js
๋ฐ html2canvas.svg.js
๋ ๋ค ํฌํจํ์
จ์ต๋๊น? ๊ทธ๋ ๋ค๋ฉด ํน์ ๋ฌธ์ ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด jsFiddle ๋๋ jsbin์ ์ ๊ณต ํ ์ ์์ต๋๊น?
๋๋ ์ด๊ฒ์ ์๋์์ผฐ๋ค. ๋ฌธ์ ๋ ๋ด๊ฐ html2canvas๋ฅผ ํ ๋ SVG๊ฐ ์์ ํ ๋ ๋๋ง๋์ง ์์๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ๋ ๋๋ง์๋ ์ฌ์ ํ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ : http://d3pie.org
๋ค์๊ณผ ๊ฐ์ด ํ์๋์ด์ผํฉ๋๋ค.
์ด๊ฒ์ html2canvas ์ดํ์ ๋ชจ์ต์ ๋๋ค.
์, ๊ฝค ์ผ์ค์คํ๋ค์. ์ด๋ ๊ฒ ์ฝ๊ฒ ์ถ์ ํ ์ ์๋๋ก ๋์ผํ ์คํฌ๋ฆฐ ์ท์ผ๋ก ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด๊ณ ๋ฐ๋ชจ๋ฅผ ์ฌ์ฉํ์ฌ jsFiddle์ ๋ํ ๋งํฌ ๋ง ์ด ์ ์์ต๋๊น? ์ด๊ฒ์ ์ค๋ ์ ์ ์ข ๊ฒฐ ๋ ์๋ ๋ฌธ์ ์์ ๋๋ฌด ๋ฉ์ด์ง๊ณ ์์ต๋๋ค. ์ ๊ณ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
๋๋ ๊ทธ๊ฒ์ํ๊ณ ์ถ์ง๋ง jsfiddle์ ์๋ก์ด html2canvas๋ฅผ ํฌํจํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ ๋๋ค. ์ฌ์ฉํ ์์๋ ์ธ๋ถ ๋งํฌ๊ฐ ์์ต๋๊น?
@nikolang http://rawgit.com/niklasvh/html2canvas/master/dist/html2canvas.js ๋ฅผ ์ฌ์ฉํ ์
๊ฐ์ฌ. ๊ทธ๋ฆฌ๊ณ SVG ๋ฒ์ ?
์๋ ํ์ธ์,
SVG๋ ๋ด ์ชฝ์์ ๋ ๋๋ง๋์ง๋ง ์๋ ๋๊ตฐ๊ฐ๊ฐ๋ณด๊ณ ํ ๊ฒ์ฒ๋ผ ๊ฒ์ ์์ผ๋ก ๋ณด์ ๋๋ค. svg ์์์ "์ฑ์ฐ๊ธฐ"์์ฑ์ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
@brainra , ๋๋ ์ฑ์ฐ๊ธฐ๋ฅผ ํฐ์์ผ๋ก ๋ง๋ค๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
// Create dummy canvas to get a white background
var destinationCanvas = document.createElement("canvas");
destinationCanvas.width = canvas.width;
destinationCanvas.height = canvas.height;
var destCtx = destinationCanvas.getContext('2d');
//create a rectangle with the desired color
destCtx.fillStyle = "#FFFFFF";
destCtx.fillRect(0,0,canvas.width,canvas.height);
//draw the original canvas onto the destination canvas
destCtx.drawImage(canvas, 0, 0);
var img = destinationCanvas.toDataURL("image/png");
'CanvasRenderingContext2D'์์ 'drawImage'์คํ ์คํจ : ์ ๊ณต๋ HTMLImageElement๊ฐ '๊นจ์ง'์ํ์ ๋๋ค. "
HTML์ svg ์์๊ฐ์์ ๋์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
๋ํ allowTaint๋ฅผ true๋ก ์ค์ ํ์ต๋๋ค. ๋๊ตฐ๊ฐ ๋๋ฅผ ๋์ธ ์ ์์ต๋๊น?
๋ค์ ์ด์ด์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค. svg ์์๋ Firefox๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์ ๋๋ก ๋ ๋๋ง๋ฉ๋๋ค.
NS_ERROR_NOT_AVAILABLE : ์ด๊ฒ์ Firefox ๋ฒ๊ทธ์ ๋๋ค : https://bugzilla.mozilla.org/show_bug.cgi?id=700533 (AFAICT) ๋ฌธ์ ๋ฅผ ๊ฐ์กฐํ๋ ํ ์คํธ ํ์ด์ง๊ฐ ์์ต๋๋ค (๋ฒ๊ทธ์์ ๋งํฌ ๋จ) http://phrogz.net/ SVG / svg_to_png.xhtml
ํด๊ฒฐ ๋ฐฉ๋ฒ / ์์ ์ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ์๋๋ฉด ๋๊ตฐ๊ฐ @mozilla ๋ฅผ ํด๊ฒฐํ ์๋ ์์ต๋๋ค. :)
ํด๊ฒฐ์ฑ
์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
http://stackoverflow.com/questions/18271898/html-and-svg-to-canvas-javascript/32457864#32457864
๋๋ ๊ฐ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ฒ์ ์๋ํ์ง๋ง ์ค์ผ ๋ ์บ๋ฒ์ค๋ก ๋๋ฉ๋๋ค. ์์ SVG๊ฐ ํ์ํฉ๋๊น?
<img svg-2-canvas-src="/assets/your.svg"/>
angular.module('APP')
.directive('svg2CanvasSrc', function() {
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs) {
var svgSrc = $attrs['svg2CanvasSrc'];
var image = new Image();
image.onload = function() {
image.onload = function() {};
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
$element[0].src = canvas.toDataURL();
};
image.src = svgSrc;
}
};
});
@remiremi ๋ด๊ฐ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ง๋ง ๊ฒฐ๊ณผ๋ ๋์ผํ๊ณ svg๊ฐ ์์ต๋๋ค ..
์๋ณธ-https: //s29.postimg.org/5lkprhx93/with_SVG.png
๊ฒฐ๊ณผ-https: //s23.postimg.org/j1otj2por/without_SVG.png
@remiremi ...์ด ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ ๋ ๋ด๊ฐ
๊ธฐ๋ณธ์ ์ผ๋ก html2canvas๋ฅผ ํธ์ถํ๊ธฐ ์ง์ ์ SVG์ ๋ช
์์ ์ธ ๋๋น / ๋์ด๋ฅผ ์ค์ ํ๋ฉด ๋๋ถ๋ถ์ ๊ฒฝ์ฐ๊ฐ ์์ ๋ฉ๋๋ค.
๋ด๊ฐํ๋ ์ผ์ ๊ด์ฌ์๋ ๋ค์ํ SVG ์์๋ฅผ ๋ฐ๋ณตํ๊ณ , .getBoundingClientRect ()๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ์์ ๋๋น / ๋์ด๋ฅผ ๊ณ์ฐํ๊ณ ์์์ ๋๋น ๋์ด ์์ฑ์ ์ค์ ํ๋ ๊ฒ์
๋๋ค. ๋ ๋๋งํ์ง ์์ง๋ง ํฝ์
๋ก Booyah
๊ทธ๋๋ ์ฌ๋ฌ ์ค ๋ฒ์ ๋ฐ div๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ์ฌ์ ํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ,
์์ค ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ณ๊ฒฝํ์ฌ์ด ๋ฌธ์ (firefox์์ svg ์์ค)๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์ฒซ์งธ, SVG ์์์๋ ํฝ์
์ฌ๋ถ์ ๊ด๊ณ์์ด ๋์ด ๋ฐ ๋๋น ์์ฑ์ด ์์ด์ผํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์์ค ์ฝ๋๋ฅผ ๋ค์์์ ๋ณ๊ฒฝํด์ผํฉ๋๋ค.
self.image.src = " data : image / svg + xml ,"+ (์ XMLSerializer ()). serializeToString (node);
์:
self.image.src = " data : image / svg + xml ,"+ encodeURIComponent ((new XMLSerializer ()). serializeToString (node));
๋ค์ ๊ทธ๊ฒ์ ์ฆ๊ธฐ์ญ์์ค.
๋๊ตฌ๋ ์ง DOM์ SVG ์์์ ๋ํด html2canvas
๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ต๋๊น?
์๊ฐ ์ข์ต๋๋ค!
+1์ ํ์ด์ด ํญ์ค์์ SVG ์์ ์คํฌ๋ฆฐ ์ท์ ์บก์ฒํ๋ ๋ฐ ์ฌ์ ํ ๋ฌธ์ ์ ๋๋ค.
{
profile: true,
allowTaint: false,
onrendered: function() {
//...done()
}
}
์ด ์๋ฃจ์
์ ์ฌ์ฉํ์ฌ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์์์์ต๋๋ค (jQuery์์ด).
ํด๊ฒฐ์ฑ
targetElem =
let nodesToRecover = [];
let nodesToRemove = [];
let svgElem = targetElem.querySelector('svg')
let parentNode = svgElem.parentNode;
// let svg = parentNode.innerHTML;
let svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" id=\"svg-annotations\" style=\"opacity: 1;\" _ngcontent-c7=\"\">\n\t\t\t<defs><marker id=\"arrow-start\" refY=\"4.5\" markerWidth=\"9.9\" markerHeight=\"9\" orient=\"auto\"><path fill=\"black\" d=\"M 9.9 0 L 9.9 9 L 0 4.5 Z\" /></marker><marker id=\"arrow-end\" refX=\"9.9\" refY=\"4.5\" markerWidth=\"9.9\" markerHeight=\"9\" orient=\"auto\"><path fill=\"black\" d=\"M 0 0 L 0 9 L 9.9 4.5 Z\" /></marker></defs><g class=\"annotation-group\" id=\"measurement-36122\" style=\"opacity: 1;\"><g class=\"annotations\"><g class=\"annotation callout elbow editable \" transform=\"translate(758.541 408.978)\"><g class=\"annotation-connector\"><path class=\"connector\" fill=\"none\" stroke=\"black\" d=\"M 0 0 L 137 137 L 162 137\" /></g><g class=\"annotation-note\" transform=\"translate(162 137)\"><g class=\"annotation-note-content\" transform=\"translate(0 3)\"><rect class=\"annotation-note-bg\" fill=\"white\" fill-opacity=\"0\" x=\"0\" width=\"104.79\" height=\"41.36\" /><text class=\"annotation-note-label\" fill=\"black\" y=\"41.36\" dx=\"0\"><tspan x=\"0\" dy=\"0.8em\" /></text><text class=\"annotation-note-title\" font-weight=\"bold\" fill=\"black\"><tspan x=\"0\" dy=\"0.8em\">Face</tspan><tspan x=\"0\" dy=\"1.2em\">:5453831.5mmยฒ</tspan></text></g><path class=\"note-line\" stroke=\"black\" d=\"M 0 0 L 104.79 0\" /><circle class=\"handle \" cursor=\"move\" fill=\"grey\" fill-opacity=\"0.1\" stroke=\"grey\" stroke-dasharray=\"5\" cx=\"0\" cy=\"0\" r=\"10\" /></g></g></g></g><g class=\"annotation-group\" id=\"measurement-59622\" style=\"opacity: 1;\"><g class=\"annotations\"><g class=\"annotation callout elbow editable \" transform=\"translate(889.656 387.507)\"><g class=\"annotation-connector\"><path class=\"connector\" fill=\"none\" stroke=\"black\" d=\"M 0 0 L 137 137 L 162 137\" /></g><g class=\"annotation-note\" transform=\"translate(162 137)\"><g class=\"annotation-note-content\" transform=\"translate(0 3)\"><rect class=\"annotation-note-bg\" fill=\"white\" fill-opacity=\"0\" x=\"0\" width=\"104.79\" height=\"41.36\" /><text class=\"annotation-note-label\" fill=\"black\" y=\"41.36\" dx=\"0\"><tspan x=\"0\" dy=\"0.8em\" /></text><text class=\"annotation-note-title\" font-weight=\"bold\" fill=\"black\"><tspan x=\"0\" dy=\"0.8em\">Face</tspan><tspan x=\"0\" dy=\"1.2em\">:5453831.5mmยฒ</tspan></text></g><path class=\"note-line\" stroke=\"black\" d=\"M 0 0 L 104.79 0\" /><circle class=\"handle \" cursor=\"move\" fill=\"grey\" fill-opacity=\"0.1\" stroke=\"grey\" stroke-dasharray=\"5\" cx=\"0\" cy=\"0\" r=\"10\" /></g></g></g></g></svg>";
this.canvas = document.createElement('canvas');
this.canvas.setAttribute('id', '_canvas');
canvg(this.canvas, svg, {renderCallback: function(){
console.log(this);
}});
nodesToRecover.push({
parent: parentNode,
child: svgElem
});
parentNode.removeChild(svgElem);
nodesToRemove.push({
parent: parentNode,
child: this.canvas
});
parentNode.appendChild(this.canvas);
let data = this.canvas.toDataURL('image/png', 0.5);
console.log(data);
๋๋ ์ด๊ฒ์ํ๊ณ ์์ง๋ง IE11์์ ๋น ์ด๋ฏธ์ง ๋ง ์ป์ต๋๋ค. ํ์ง๋ง ์น ํ์ด์ง์์ ์บ๋ฒ์ค๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ์๋ฌด๋ ๋ด๊ฐ ์ฌ๊ธฐ์ ๋ญ ์๋ชปํ๊ณ ์๋์ง ๋์ ์ฃผ์๊ฒ ์ต๋๊น?
์๋
ํ์ธ์. <image>
ํ๊ทธ๊ฐ์์ ๋ SVG๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ํ SVG
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200" width="200"/>
</svg>
jsfiddle http://jsfiddle.net/maestro888/fmjywksq/์ ์ํ
๊ฐ๋จํ ํด๊ฒฐ์ฑ ์ ์ฐพ์์ต๋๋ค.
svg ์ด๋ฏธ์ง์ ๋๋น์ ๋์ด๊ฐ ์๋์ง ํ์ธํ์ญ์์ค.
SVG๋ ์ด๋ฏธ์ง์ฒ๋ผ ์ธก์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ถฉ๋ถํ ์ธ์๊ฐ ์์ต๋๋ค.
์ด๊ฒ์ ์ฌ์ค์ด์ง๋ง IE11์๋ ์ ์ฉ๋์ง ์์ต๋๋ค.
์ ๋ฆฌํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค.
๋ฐฉ๊ธ JS Fiddle์ ํ์ธํ๋ฉด ์ด๋ฏธ์ง๊ฐ ํ์๋ฉ๋๋ค.
๋ฌธ์ ์ธ์ฌ,
๋ฒ๋๋ TA ๋ฒ ์ด์ปค
2019 ๋
3 ์ 27 ์ผ ์์์ผ ์คํ 4:34 Alessandro Candini [email protected]
์ผ๋ค :
๊ฐ๋จํ ํด๊ฒฐ์ฑ ์ ์ฐพ์์ต๋๋ค.
svg ์ด๋ฏธ์ง์ ๋๋น์ ๋์ด๊ฐ ์๋์ง ํ์ธํ์ญ์์ค.
๊ทธ๋ ์ง ์์ผ๋ฉด SVG๋ฅผ ์ธก์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ธ์๊ฐ ์ถฉ๋ถํ์ง ์์ต๋๋ค.
์ด๋ฏธ์ง ์บ์ฒ๋ผ.์ด๊ฒ์ ์ฌ์ค์ด์ง๋ง IE11์๋ ์ ์ฉ๋์ง ์์ต๋๋ค.
โ
๋๊ธ์ ๋ฌ์ ๊ธฐ ๋๋ฌธ์ ์์ ํ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/niklasvh/html2canvas/issues/95#issuecomment-477242192 ,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AM7ZzLPsl0WJS7gGI9npSsRxR33FCnN9ks5va52bgaJpZM4AD-Sb
.
์ฌ๊ธฐ์ ์คํ ์ค๋ฒํ๋ก ์ ๋ํด๋ณด๊ณ ๋ canvg ์๋ฃจ์ ์ ์ฐพ์์ต๋๋ค. IE11์์ ์๋ฒฝํ๊ฒ ์๋ํฉ๋๋ค!
๋ค์ ์ ๊ตํด์ง ์ค ๋ํซ, jQuery ์ข ์์ฑ ์ ๊ฑฐ :
let svgIcons = document.querySelectorAll('.svg-icon');
for (let i = 0; i < svgIcons.length; ++i) {
let curSvg = svgIcons[i];
let canvas;
let xml;
// Size and color needed for every browser
curSvg.setAttribute('width', curSvg.parentNode.offsetWidth);
curSvg.setAttribute('height', curSvg.parentNode.offsetHeight);
curSvg.setAttribute('style', 'fill: blue');
canvas = document.createElement('canvas');
canvas.className = 'screenShotTempCanvas';
xml = new XMLSerializer().serializeToString(curSvg);
canvg(canvas, xml);
curSvg.parentNode.insertBefore(canvas, curSvg.nextSibling);
curSvg.style.display = 'none';
}
ํฐ
2019 ๋
3 ์ 28 ์ผ ๋ชฉ์์ผ 08:49 Alessandro Candini, [email protected]
์ผ๋ค :
canvg https://github.com/canvg/canvg ์๋ฃจ์ ์ ์ฐพ์์ต๋๋ค.
์ฌ๊ธฐ์ ์คํ ์ค๋ฒํ๋ก์ ๋ํด๋ณด๊ณ ํ์ต๋๋ค.
https://stackoverflow.com/questions/34042440/using-html2canvas-to-render-a-highcharts-chart-to-pdf-doesnt-work-on-ie-and-fir :
IE11์์ ์๋ฒฝํ๊ฒ ์๋ํฉ๋๋ค!โ
๋๊ธ์ ๋ฌ์ ๊ธฐ ๋๋ฌธ์ ์์ ํ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/niklasvh/html2canvas/issues/95#issuecomment-477503221 ,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AM7ZzKNy1GOgQU9TVv7PGCi4fJvYSxDVks5vbIIOgaJpZM4AD-Sb
.
์๋
ํ์ธ์ @niklasvh html2canvas ์๋ฐ ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ
"๋ฟ๋ง ์๋๋ผ anguar6 ์์ฉ ํ๋ก๊ทธ๋จ์"1.0.0-rc.1 "๋ฒ์ ๋ ๋ฌธ์ ๋ชฉ๋ก์ ์๋ต์ ๋ฐ๋ผ ๋ฌธ์ ๊ฐ ์ฌ ๊ฒ์
๋๋ค svg๋ ๋์ด์ ๋๋น๋ฅผ ํฌํจํ์ง ์์ง๋ง ์ ๊ฒฝ์ฐ์๋ Svg๊ฐ 100 % ๋์ด์ ๋๋น์ ์ค์ฒฉ ๋ div์๋ svg ํ๊ทธ๋ ํฌํจ๋์ด ์๊ณ ๊ธฐ์กด ์บ๋ฒ์ค๋ ์ค์ฒฉ๋์ด ์์ต๋๋ค. ๋ด ํ์ด์ง๋ฅผ png ์ด๋ฏธ์ง๋ก ๋ด๋ณด๋ผ ์ ์์ง๋ง ์ด๋ฏธ์ง์๋ ์ถฉ๋ ๋ svg ์์ด์ฝ ๋ง ํฌํจ๋์ด ์๊ณ ๊ธฐ์กด ์บ๋ฒ์ค๋ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ๋ด ๋ค๋ฅธ ํ์ด์ง svg๋ ๋ชจ๋ ์ถฉ๋ ์ด๋ฏธ์ง๋ก ํ์๋ฉ๋๋ค. ์ฐธ๊ณ ๋ฅผ ์ํด ์ฌ๊ธฐ์ ์คํฌ๋ฆฐ ์ท์ ์ฒจ๋ถํ์ต๋๋ค. ํ ๋ฒ ๋ณด์๊ณ ๊ฐ์ฌํฉ๋๋ค.
html2canvas (this.screen.nativeElement, {useCORS : true}). then (canvas => {
this.canvas.nativeElement.src = canvas.toDataURL ( 'image / png');
this.downloadLink.nativeElement.href = canvas.toDataURL ( 'image / png');
this.downloadLink.nativeElement.download = 'screenshot.png';
this.downloadLink.nativeElement.click ();
});
testpdf (1) .pdf
์๋
ํ์ธ์,
์ถ์ ์ป๊ณ ์์ง๋ง ์ฐจํธ์ ๋๋จธ์ง ์์ญ์ ๊ฒ์ ์์
๋๋ค. ์ด๋ ํ ์ ์
์๋ ํ์ธ์ @niklasvh html2canvas ์๋ฐ ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ
"๋ฟ๋ง ์๋๋ผ anguar6 ์์ฉ ํ๋ก๊ทธ๋จ์"1.0.0-rc.1 "๋ฒ์ ๋ ๋ฌธ์ ๋ชฉ๋ก์ ์๋ต์ ๋ฐ๋ผ ๋ฌธ์ ๊ฐ ์ฌ ๊ฒ์ ๋๋ค svg๋ ๋์ด์ ๋๋น๋ฅผ ํฌํจํ์ง ์์ง๋ง ์ ๊ฒฝ์ฐ์๋ Svg๊ฐ 100 % ๋์ด์ ๋๋น์ ์ค์ฒฉ ๋ div์๋ svg ํ๊ทธ๋ ํฌํจ๋์ด ์๊ณ ๊ธฐ์กด ์บ๋ฒ์ค๋ ์ค์ฒฉ๋์ด ์์ต๋๋ค. ๋ด ํ์ด์ง๋ฅผ png ์ด๋ฏธ์ง๋ก ๋ด๋ณด๋ผ ์ ์์ง๋ง ์ด๋ฏธ์ง์๋ ์ถฉ๋ ๋ svg ์์ด์ฝ ๋ง ํฌํจ๋์ด ์๊ณ ๊ธฐ์กด ์บ๋ฒ์ค๋ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ๋ด ๋ค๋ฅธ ํ์ด์ง svg๋ ๋ชจ๋ ์ถฉ๋ ์ด๋ฏธ์ง๋ก ํ์๋ฉ๋๋ค. ์ฐธ๊ณ ๋ฅผ ์ํด ์ฌ๊ธฐ์ ์คํฌ๋ฆฐ ์ท์ ์ฒจ๋ถํ์ต๋๋ค. ํ ๋ฒ ๋ณด์๊ณ ๊ฐ์ฌํฉ๋๋ค.
html2canvas (this.screen.nativeElement, {useCORS : true}). then (canvas => {
this.canvas.nativeElement.src = canvas.toDataURL ( 'image / png');
this.downloadLink.nativeElement.href = canvas.toDataURL ( 'image / png');
this.downloadLink.nativeElement.download = 'screenshot.png';
this.downloadLink.nativeElement.click ();
});
๊ฐ์ ๋ฌธ์ , ๋ณต์ ๋ ๋ฌธ์์์ svg๋ฅผ ์ฐพ๋ ๋์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
html2canvas๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ์ผ์์ ์ผ๋ก ๋์ด์ ๋๋น๋ฅผ SVG๋ก ์ค์ ํ๊ณ ์์ต๋๋ค. ์ด๋ ๊ฒํ๋ฉด svg๋ฅผ ์บก์ฒ ํ ์ ์์ต๋๋ค.
var selectedItem = document.querySelector ( ". chartWrapper");
var svgElements = selectedItem.querySelectorAll ( 'svg');
for (let i = 0; i <svgElements.length; i ++) {
selectedItem.getElementsByTagName ( "svg") [i] .style.height = document.getElementsByTagName ( "svg") [i] .getBoundingClientRect (). height;
selectedItem.getElementsByTagName ( "svg") [i] .style.width = document.getElementsByTagName ( "svg") [i] .getBoundingClientRect (). width;
}
html2canvas (selectedItem, {backgroundColor : '# 000', allowTaint : true}). then (canvas => {
var myImage = canvas.toDataURL ( "image / png"). replace ( "image / png", "image / octet-stream");
window.location.href = myImage;
})
for (let i = 0; i <svgCount; i ++) {
selectedItem.getElementsByTagName ( "svg") [i] .style.height = '100 %';
selectedItem.getElementsByTagName ( "svg") [i] .style.width = '100 %';
}
// use html2canvas in react project when i need a screenshot for the svg
/**
* svg to canvas
* <strong i="5">@param</strong> targetElem
* <strong i="6">@return</strong> {Promise<[]>} // return svg elements
*/
async function svgToCanvas(targetElem) {
let nodesToRecover = [], nodesToRemove = [], svgElems = targetElem.querySelectorAll('svg');
for (let i = 0; i < svgElems.length; i++) {
let node = svgElems[i], parentNode = node.parentNode, svg = parentNode.innerHTML,
canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.setAttribute('data-cover', 'svg');
const v = await Canvg.from(ctx, svg);
v.start();
// record svg elements
nodesToRecover.push({
parent: parentNode,
child: node
});
parentNode.removeChild(node);
// record canvas elements
nodesToRemove.push({
parent: parentNode,
child: canvas
});
parentNode.appendChild(canvas);
}
return nodesToRecover;
}
/**
* recover canvas to svg
* <strong i="7">@param</strong> targetElem
* <strong i="8">@param</strong> svgElems // need to recover svg elements
* <strong i="9">@return</strong> *
*/
function recoverCanvasToSvg(targetElem, svgElems) {
let canvasElems = targetElem.querySelectorAll("canvas[data-cover='svg']");
if(!targetElem){
throw new Error('must have targetElem param')
}
if(!isArray(svgElems) && svgElems.length !== canvasElems.length) {
throw new Error('svgElems must be an Array, and it`s length equal to canvasElems`s length')
}
for(let i = 0; i < canvasElems.length; i++){
let node = canvasElems[i], parentNode = node.parentNode;
parentNode.removeChild(node);
parentNode.appendChild(svgElems[i]?.child);
}
}
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ,
์์ค ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ณ๊ฒฝํ์ฌ์ด ๋ฌธ์ (firefox์์ svg ์์ค)๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์ฒซ์งธ, SVG ์์์๋ ํฝ์ ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋์ด ๋ฐ ๋๋น ์์ฑ์ด ์์ด์ผํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์์ค ์ฝ๋๋ฅผ ๋ค์์์ ๋ณ๊ฒฝํด์ผํฉ๋๋ค.
self.image.src = " data : image / svg + xml ,"+ (์ XMLSerializer ()). serializeToString (node);
์:
self.image.src = " data : image / svg + xml ,"+ encodeURIComponent ((new XMLSerializer ()). serializeToString (node));
๋ค์ ๊ทธ๊ฒ์ ์ฆ๊ธฐ์ญ์์ค.