📸

DOMをSVGパワーで丸ごと画像にするやつの自力実装例

2023/02/03に公開

これは何ですか?

DOMをforeignObjectでSVG内に包んで画像にします

👆こんな感じで一発キャプチャできました
Stackblitz

"use strict";
      function captureDocument({ target, result }) {
        const { clientWidth, clientHeight, innerHTML } = target;
        const reader = new FileReader();
        reader.readAsDataURL(
          new Blob(
            [
              `
				<svg xmlns="http://www.w3.org/2000/svg" id="captureSVG" width="${clientWidth}" height="${clientHeight}">
					<foreignObject width="${clientWidth}" height="${clientHeight}" x="0" y="0">
						${innerHTML}
					</foreignObject>
				</svg>
			`,
            ],
            { type: 'image/svg+xml' }
          )
        );
        reader.onloadend = () =>
          Object.assign(new Image(), {
            src: reader.result,

            onload() {
              const canvas = Object.assign(document.getElementById('buffer'), {
                width: clientWidth,
                height: clientHeight,
              });
              const renderBuffer = canvas.getContext('2d');
              renderBuffer.clearRect(0, 0, clientWidth, clientHeight);
              renderBuffer.drawImage(this, 0, 0, clientWidth, clientHeight);
              result.src = canvas.toDataURL();
            },
          });
      }

課題点

  • リンクで埋め込んだ<img>が読み込まれる前に即drawImage()が発動するので、一度パースしてfetch後base64エンコードする等の措置が欲しいです

Discussion