JSFiddle - React, Tailwind, and code Playground
HTML
<div>
<svg id="target-svg" width="300" height="200">
<!-- https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Getting_Started -->
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
</div>
<div>
<select id="action">
<option value="show-newtab">別タブ表示</option>
<option value="show-img">imgタグで表示</option>
<option value="show-download-link">ダウンロードリンクを作る</option>
</select>
<button id="show-image">
実行
</button>
</div>
<div id="result">
<p>
ボタンを押すとSVGが画像に変換され、応じた処理が行います
</p>
</div>
JavaScript
const ACTION_LIST = {
"show-newtab"(bloburl) {
// 別タブ表示する
const newtab = window.open(bloburl, '_blank');
newtab.addEventListener('beforeunload', function(ev) {
console.log("revoke bloburl", bloburl)
URL.revokeObjectURL(bloburl);
})
},
"show-img"(bloburl) {
// HTMLにimgタグを埋め込む
const newimg = document.createElement('img');
newimg.src = bloburl;
document.getElementById('result').appendChild(newimg)
// TODO: URL.revokeObjectURL(bloburl); をすべき
},
"show-download-link"(bloburl) {
const a = document.createElement('a');
a.href = bloburl;
a.download = "お好きな名前.png";
a.innerText = "ダウンロード!"
document.getElementById('result').appendChild(a);
// TODO: URL.revokeObjectURL(bloburl); をすべき
// TODO: 複数ファイルダウンロード扱いにされるかも
},
}
document.getElementById('show-image').addEventListener('click', function(ev) {
const svgEl = document.getElementById('target-svg');
const action = document.getElementById('action').value;
// XMLにシリアライズしてBlob化
const serializer = new XMLSerializer();
const svgurl = URL.createObjectURL(new Blob([serializer.serializeToString(svgEl)], {
type: 'image/svg+xml'
}));
// Blobをimgとして表示
const svgImage = document.createElement('img');
svgImage.addEventListener('load', function() {
// キャンバスに描画
const canvas = document.createElement('canvas');
canvas.width = svgImage.width;
canvas.height = svgImage.height;
const canvasCtx = canvas.getContext('2d');
canvasCtx.drawImage(svgImage, 0, 0);
// キャンバスからBlobを得る
canvas.toBlob(function(blob) {
const bloburl = URL.createObjectURL(blob);
ACTION_LIST[action](bloburl)
});
URL.revokeObjectURL(svgurl);
}, {
once: true
});
// 何らかの理由で、SVGのBlobのURLが読み込みできないと何も起きずに死ぬのでハンドリングしておく
svgImage.addEventListener('error', (err) => console.log("Load failed.", err))
// ここでロードされる
svgImage.src = svgurl;
})