CanvasにSVGファイルを読み込んで表示する
SVGは、Illustratorから直接ファイルを書き出すことができ、
書き出されたファイルのSVGのタグをHTML内に書き込むだけで、
HTML内に描画することができるので、扱いやすいですが、
多数の要素からなる、再描画を多く必要とするようなグラフィックが求められる場合、
パフォーマンスが著しく低下するという弱点があります(参考: SVG と Canvas: どちらを選ぶか (Windows))。
多数の要素からなる、再描画を多く必要とするようなグラフィックは、Canvasの方が向いており、
そういったグラフィックでは、高いパフォーマンスを発揮します。
しかし、CanvasはSVGのように、タグを置けば描画してくれたり、CSSで操作して色を変えたりアニメーションさせるといったことはできず、
より高度なグラフィックのプログラムの知識が必要となります。
描画した各要素をクリックしてリンクさせるといったことも、
SVGではHTMLのようにaタグで目的の要素を囲めばいいだけですが、
Canvasでは要素の位置を特定し、
マウスの座標との当たり判定を設けるなどの処置が必要で、
そういった操作に関するプログラムの必要性もあります。
ただ、やはり今後パフォーマンスの高いグラフィックを使ったWEBアプリなどを作成する上で、
Canvasは必要不可欠だと思いましたので、
今回は、Illustratorで書きだしたSVGファイルを、
Canvasの要素として読み込んで描画する方法がないか調べて、やってみました。
↓参考にさせていただいたサイト
DOM オブジェクトを Canvas に描画する – HTML | MDN
↓こちらが作ってみたもの
DEMO
方法
1.Illustratorで書きだしたSVGファイルの拡張子を.txtに変更する
Canvasで描画するときに、今回はBlobというJavaScriptのAPIを利用するのですが、
そのときに、テキスト情報としてSVGのデータを渡すので、SVGファイルの拡張子を.txtにして、
テキストファイルとして扱います。
1 | svg-file.svg → svg-file.txt //SVGファイルの拡張子を変更 |
2.AjaxでテキストファイルにしたSVGを読み込み、Imageオブジェクトに変換する
jQueryを使って、Ajaxによって、先ほど用意したファイルを読み込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //SVGファイルの読み込み $.ajax({ url: "images/logo.txt" }) .done(function(data) { var canvas = document.getElementById("canvas"), //canvasの要素を指定 ctx = canvas.getContext("2d"), //canvasの初期設定 DOMURL = self.URL || self.webkitURL || self, //URLオブジェクトを取得 img = new Image(), //Imageオブジェクトの呼び出し svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"}), //読み込んだSVGデータを元に、画像のFileオブジェクトを作成 url = DOMURL.createObjectURL(svg); //画像のFileオブジェクトのURLを作成 img.src = url; //Imageオブジェクトのsrcに画像のFileオブジェクトのURLを指定 img.onload = function() { DOMURL.revokeObjectURL(url); //画像のFileオブジェクトのURLを削除 ・・・ }; }); |
その後、Canvasの初期設定を行い、
Blob()を使って、SVGファイルを元に描画を行ったラスターの仮想画像ファイルを作成し、
その仮想の画像ファイルをImageオブジェクトのsrcとして指定します。
3.Canvasに描画する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | //AnimationFrameの用意 window.requestAnimationFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element){ window.setTimeout(callback, 1000 / 60); }; })(); //SVGファイルの読み込み $.ajax({ url: "images/logo.txt" }) .done(function(data) { var canvas = document.getElementById("canvas"), //canvasの要素を指定 ctx = canvas.getContext("2d"), //canvasの初期設定 DOMURL = self.URL || self.webkitURL || self, //URLオブジェクトを取得 img = new Image(), //Imageオブジェクトの呼び出し svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"}), //読み込んだSVGデータを元に、画像のFileオブジェクトを作成 url = DOMURL.createObjectURL(svg); //画像のFileオブジェクトのURLを作成 img.src = url; //Imageオブジェクトのsrcに画像のFileオブジェクトのURLを指定 img.onload = function() { DOMURL.revokeObjectURL(url); //画像のFileオブジェクトのURLを削除 //画像のアニメーション var x = -300; function animationLoop() { if(x > 960) x = -300; x += 5; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, x, 50); requestAnimationFrame(animationLoop); } animationLoop(); }; }); |
それができたら、.drawImage()によって、CanvasにSVGから作成した画像を描画すれば完了です。
一度読み込んでしまえば、SVGデータではなくラスターの画像データとして扱うことができるので、
元のファイルはSVGですが、Canvasの高いパフォーマンスを邪魔すること無く扱うことができます。
Blob()や.createObjectURL()がFileAPIというIE9以下では対応できないものではありますが、
今後、利用の幅が広がっていくのではないかと思います。
その他参考サイト
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE