何度もお目にかかっていたCanvasさん。
避けに避け続けていましたが、業務で使わざるを得ない状況になったので、
お勉強と実装をしてみました。
最終的に、Vue3で、svgをpngにしたい。
※svgは、インラインで直接表示させているもの。
最初、参考サイトの通りに実装しましたが、
svgの読み込みが上手く行いかなかった&エラーがあったので、
不具合・エラーを直したものを、こちらに残しておきます・・・。
Canvasとは
- HTML5とJavaScript(以下、JS)でブラウザ上に図が描けるもの
- <canvas>タグにJSで、図を描画していく
- Canvasでレイアウトを決めた部分には、CSSでレイアウトを適用できない
SVGのPNG画像変換
大まかな流れとしては、CanvasとJSを使って、svgをPNG画像に変換・描画し、PNG画像のデータをダウンロード。
手順
- XMLSerializerを使って、SVG画像のデータを取り出す
- CanvasとJSを使って、PNG形式に変換
- CanvasのtoDataURL()で、PNG画像のURIを取得
- ローカルにpng画像をダウンロード
コード
// vue <div @click="download()"> <svg id="sample">....いろいろ描いてあります.....</svg> </div>
const download = () => {
// svg domを取得
const svg = document.getElementById('sample')
// canvasを準備
let canvas = document.createElement('canvas')
canvas.width = svg.width.baseVal.value
canvas.height = svg.height.baseVal.value
// 描画をするための、canvasの組み込みオブジェクトを準備
const ctx = canvas.getContext('2d')
// imgオブジェクトを準備
let image = new Image()
// imageの読み込みが完了したら、onloadが走る
image.onload = () => {
// SVGデータをPNG形式に変換する
// canvasに描画する drawImage(image, x座標, y座標, 幅, 高さ)
ctx.drawImage(image, 0, 0, image.width, image.height)
// ローカルにダウンロード
let link = document.createElement("a")
link.href = canvas.toDataURL() // 描画した画像のURIを返す data:image/png;base64
link.download = "canvas.png"
link.click()
}
// 読み込みに失敗したらこっちが走る
image.onerror = (error) => {
console.log(error)
}
// SVGデータをXMLで取り出す
const svgData = new XMLSerializer().serializeToString(svg)
// この時点で、上記のonloadが走る
image.src = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(unescape(encodeURIComponent(svgData)))
}
コード解説
canvas.getContext(“2d”)
getContext(“2d”) オブジェクトは、線、ボックス、円、などを描画するメソッドを持っています。
http://memopad.bitter.jp/w3c/html5/html5_ref_canvas.html
使える描画メソッド一覧も、上記のサイトにあります。
例えば、drawImage()メソッドは、canvasに画像を描画する。
const image = new Image()
const ctx = canvas.getContext('2d')
ctx.drawImage(image, x座標, y座標, 幅, 高さ)
new Image()
The Image() constructor creates and returns a new HTMLImageElement object representing an HTML <img> element which is not attached to any DOM tree. It accepts optional width and height parameters. When called without parameters, new Image() is equivalent to calling document.createElement(“img”).
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement
新しいHTMLImageElementインスタンス(<img>)を作成するコンストラクタ
つまり、new Image()をすることで、imgタグを作成できる
image.onload
image.srcに画像のパスを渡して、読み込み完了したタイミングで、onloadが走る。
drawImage
drawImageは、<canvas>へ画像を描画する。
serializeToString
XMLSerializerのメソッドで、HTMLElementオブジェクトを、XML出力する。
new XMLSerializer().serializeToString(HTMLElementオブジェクト)
btoa
- WindowOrWorkerGlobalScope.btoa()メソッドは、バイナリ文字列から、Base64でエンコードされたASCII文字列を生成する。
- 使いどころ:画像のデータを文字列でsrcに渡したいときなど
- btoaでデータをエンコードしている
- atobで再度デコードできる
toDataURL
- canvasのメソッド
- 画像の data URI を返す。
- typeパラメーターで、画像ファイルの形式を指定できる(デフォルトはpng)
- 返り値の例:data:image/png;base64,iVBORw0KGgoAAAANSUhE……
用語
SVG
- スケーラブル・ベクター・グラフィックス、Scalable Vector Graphics
- 画像形式の1つ
- XMLをベースにしたベクターデータで画像を描画(拡大・縮小しても画質が損なわれない)
- イラレ以外にも、d3jsというもので作成できるらしい
XMLSerializer
XMLSerializer インターフェースは、DOM ツリーを表す XML 文字列を構築するための serializeToString() (en-US) メソッドを提供します。
https://developer.mozilla.org/ja/docs/Web/API/XMLSerializer
- DOMから、XML文字列を生成するためのクラス
- 最新のブラウザならだいたい対応している(チェック)
- new XMLSerializer() オブジェクトを使用する
参考サイト
お世話になりました・・・(愛)
コメント