📸
DOMをSVGパワーで丸ごと画像にするやつの自力実装例
これは何ですか?
DOMを丸ごとforeignObjectで包んで画像にするコードのプロトタイプです
デモページではcontenteditableな<div>
に貼り付けてキャプチャできます
僕自身vscodeの成果物を画像化してツイートする等で何回か使いましたが、肝心のツイッターが凍結してしまいました(異議申し立て済)
👆こんな感じで一発キャプチャできました
HTML全文 | デモ
const captureDOM = (selector, sendTo) => {
let dom = document.querySelector(selector);
let width = dom.clientWidth;
let height = dom.clientHeight;
console.log("capturing");
let svgData = `
<svg id="captureSVG" width="${width}" height="${height}">
<foreignObject width="${width}" height="${height}" x="0" y="0">
${dom.innerHTML}
</foreignObject>
</svg>
`;
let cvs = document.getElementById("result");
cvs.width = width;
cvs.height = height;
let c2d = cvs.getContext('2d');
let data = new DOMParser().parseFromString(svgData, "text/html");
let img = new Image();
img.src = `
data:image/svg+xml;base64,${
window.btoa(
unescape(
encodeURIComponent(
new XMLSerializer().serializeToString(data.querySelector("#captureSVG"))
)
)
)
}
`;
img.onload = () => {
c2d.clearRect(0, 0, width, height);
c2d.drawImage(img, 0, 0, width, height);
document.querySelector(sendTo).src = cvs.toDataURL();
};
};
課題点
- リンクで埋め込んだ
<img>
が読み込まれる前に即drawImage()
が発動するので、一度パースしてfetch後base64エンコードする等の措置が欲しいです
Discussion