こうする

async function loadAsImage(svg) {
	return new Promise((resolve, reject) => {
		const svgXml = new XMLSerializer().serializeToString(svg);

		const blob = new Blob([svgXml], { type: 'image/svg+xml' });
		const url = URL.createObjectURL(blob);

		const img = new Image();
		img.onload = () => {
			URL.revokeObjectURL(url);
			resolve(img);
		};
		img.onerror = (e) => {
			URL.revokeObjectURL(url);
			reject(e);
		};
		img.src = url;
		console.log(url);
	});
}

const img = await loadAsImage(svg);
ctx.drawImage(img, 0, 0);

ポイント

XMLSerializer を使っているところ。svg.outerHTML だと HTML 的に解釈された svg なので、xmlns が入らず、単体の SVG としては正しくないものになっている。

ただ、ブラウザ自体は HTML の svg が xmlns を持っていることは知っているため、XMLSerializer を使うことで正しい svg にできる。

  1. トップ
  2. tech
  3. HTML5 の svg 要素 を canvas に描く方法