SVGとCanvasのどっちを使えば良いのか仕様が決められないという声をエンジニアから相談されることがあります。
マウスやHTMLの各種のイベントと連動したい場合はSVGで、描画を重視する場合はCanvasが良いという風に考えられます。
またsvgの最大のメリットは、拡縮できるベクター画像なので、写真画像以外のアイコンやインサート画像などは、svgにしておくとWEBページの汎用性が増すでしょう。
canvasの描画機能は、gameなどでもよく使われているようなので、今回はcanvasの描画について色々と検証してみたいと思います。
canvasに外部画像を読み込んで表示する
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>canvas</title>
<link rel='stylesheet' href='common.css'>
</head>
<body>
<canvas id='canvas'></canvas>
<!-- <img src="image.png" style="width:100px;height:100px;"> -->
<script type='text/javascript' charset='UTF-8' src='common.js'></script>
</body>
</html>
canvas{
box-shadow:2px 2px 8px rgba(0,0,0,0.7);
/* border-radius:8px; */
}
var canvas = document.getElementById("canvas");
canvas.width = 300;
canvas.height = 300;
var ctx = canvas.getContext('2d');
var img1 = new Image();
img1.src = "image.svg";
ctx.drawImage(img1, 0, 0 ,100,100);
var img2 = new Image();
img2.src = "image.png";
ctx.drawImage(img2, 100, 0 ,100,100);
解説
canvasに対して、"var ctx = canvas.getContext('2d');"を扱うのは、どうやらcanvasのセオリーとなっているようです。
確かにこれで統一しておくと、かなり管理は楽にできそうです。
イメージの読み込みは、"new Image()"で、定義したインスタンスイメージエレメントに対して、src属性で画像のファイルパスを指定すると、画像がメモリに作成されます。
それを、"drawImage()"でセットしてあげるだけなのですが、リファレンスは、以下のようになります。
ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
sx : 元画像(X)
sy : 元画像(Y)
sw : 元画像サイズ(W)
sh : 元画像サイズ(H)
dx : 配置座標(X)
dy : 配置座標(Y)
dw : 表示サイズ(W)
dh : 表示サイズ(H)
フルリファレンスが上記ですが、画像設置を簡単に書くと、以下のようにも書けます。
ctx.drawImage(image, dx, dy, dw, dh)
dx : 配置座標(X)
dy : 配置座標(Y)
dw : 配置サイズ(W)
dh : 配置サイズ(H)
さらに、dwとdhも任意なのですが、画像の表示サイズは記述するようにしたほうが無難です。
画像読み込み問題
上記のソースコードで、何度かブラウザをリロードしていると、たまに画像が表示されないことがあります。
スッパーリロードとしてキャッシュをクリアした直後の表示の際に、画像が真っ白になってしまいます。
原因は、画像が読み込まれる前にdraw処理をして結果透明な画像が表示されている状態のようです。
これを回避するために、画像読み込みには必ずonload処理を付けてあげましょう。
var canvas = document.getElementById("canvas");
canvas.width = 300;
canvas.height = 300;
var ctx = canvas.getContext('2d');
var img1 = new Image();
img1.src = "image.svg";
img1.onload = (function(img){
ctx.drawImage(img, 0, 0 ,100,100);
}).bind(this,img1);
var img2 = new Image();
img2.src = "image.png";
img2.onload = (function(img){
ctx.drawImage(img, 100, 0 ,100,100);
}).bind(this,img2)
都度上記のように、onloadをするパターンと、canvas設置のタイミングで事前にimage一覧を一括で読み込んで、全てがloadされてから、canvasコントロールを始めるというパターンがあり、どちらで行うかは、システム構成によって変えればいいでしょう。
0 件のコメント:
コメントを投稿