Skip to content

Instantly share code, notes, and snippets.

@mizchi
Last active May 8, 2020 00:19
Show Gist options
  • Save mizchi/a821dd845768f05c488bac87d28581dc to your computer and use it in GitHub Desktop.
Save mizchi/a821dd845768f05c488bac87d28581dc to your computer and use it in GitHub Desktop.

html を 画像化する https://github.com/gripeless/pico の、コアっぽい部分を抜き出した

手順

  • html を svg の foreignObject (任意HTMLの埋め込み要素) に描画
  • svg を XMLSerializer で data-uri 化
  • new Image して img.src に data-uri を流し込む
  • canvas に svg を読み込んだ img を renderImage する
  • canvas.toDataURL("image/png") で任意のフォーマットで吐き出し
const template = (html: string, width: number, height: number) => `
<div style="position: absolute; left: -1000000;">
<svg id="capture-root" width=${width} height=${height}>
<foreignObject width=${width} height=${height}>
<body>
${html}
</body>
</foreignObject>
</svg>
</div>
`;
function captureAsDataURI(html: string, width: number, height: number) {
const el = document.createElement("div");
el.innerHTML = template(html, width, height);
document.body.appendChild(el);
const encoded = window.encodeURIComponent(
new XMLSerializer().serializeToString(
document.querySelector("#capture-root")
)
);
el.remove();
return `data:image/svg+xml;charset=utf-8,${encoded}`;
}
async function run() {
const img = new Image();
const dataUri = captureAsDataURI(
"<p>Here is a paragraph that requires word wrap</p></body>",
300,
300
);
img.src = dataUri;
await new Promise((r) => (img.onload = r));
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
const pngDataUrl = canvas.toDataURL("image/png", 1);
canvas.remove();
console.log(pngDataUrl);
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment