復興ログ

未来の被災地にいるアナタと数十年後のキミたちへ。すべての記録を残します。

HTML5 canvas基礎

f:id:hebita164:20100322170859j:image:right
HTML5のキャンバス(canvas)の基本的な使い方をまとめてみました。
ブラウザのJavascriptAPI操作により、右のような画像のクリッピング操作を簡単にすることができます。
HTML5canvasのサンプルのすべてはこちらに用意してみました。
また、HTML5 canvas関連APIもご参照ください。

キャンバスの使用方法

キャンバスの定義は以下の方法で簡単に定義ができます。

<canvas id="canvas1" width="300" height="200"></canvas>

CanvasJavascript API

<canvas id="canvas1" width="300" height="200"></canvas>

<script type="text/javascript"><!--
	// canvas要素のオブジェクトを取得
	var canvas = document.getElementById("canvas1");

	// 描画コンテキストを取得する
	var context = canvas.getContext("2d");

	// 四角形の描画
	context.fillRect(0,0,150,100);

	// テキストの描画
	context.fillText("蛇田.jp",155 ,110);

	// 線の描画の開始
	context.beginPath();

	// 線の描画
	context.moveTo(0,100);
	context.lineTo(300,100);
	context.moveTo(150,0);
	context.lineTo(150,200);

	// キャンバスの枠として四角形を描画する
	context.rect(0,0,300,200);

	// 画面への書き出し
	context.stroke();

	// 線の描画を終了
	context.closePath();

//--></script>

サンプル1 - 基礎

お絵かきのための流れは

  1. canvasタグを記述する。
  2. canvasのDOMオブジェクトを取得し、getContext("2d")というメソッド呼び出しにより、描画コンテキストを取得する。
  3. 描画コンテキストが持つさまざまなメソッドを用いて、グラフィックスの描画を行なう。

画像の描画

imgタグを用いることなく画像をcanvasに描くことができます。

<canvas id="canvas2" width="300" height="200"></canvas>

<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas2 = document.getElementById("canvas2");
	// 描画コンテキストを取得する
	var cx2 = canvas2.getContext("2d");
	// img要素を生成
	var image2 = new Image();
	// 画像の読み込みが終わったら、キャンバスへの書き出しを行なう
	image2.onload = function(){
		// キャンバスいっぱいに画像を表示
		cx2.drawImage(image2,0,0,canvas2.width,canvas2.height);
	};
	// 画像のロードを開始
	image2.src = "canvas_image.jpg";

//--></script>

サンプル2 - 画像の描画
ポイントは画像の読み込みが終わったあとに画像が描かれるようにすること。
cx.drawImageでキャンバスに画像を流し込みます。

線を描く

Javascriptで計算をさせることで線を描くことが出来ます。

二次ベジェ曲線
<h4>二次ベジェ曲線</h4>
<canvas id="canvas3" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas3");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// キャンバスの原点に移動
	cx.moveTo(0,0);
	// ベジェ曲線を描画
	cx.quadraticCurveTo(50,100,100,0);
	// 線を書き出し
	cx.stroke();
//--></script>

cx.quadraticCurveTo(cpx,cpy,x,y);
二次ベジェ曲線を描画します。現在位置と、引数で渡された座標(x,y)をつなぐ曲線を描画し、曲線のカーブは(cpx,cpy)の座標によって決まります。

三次ベジェ曲線
<h4>三次ベジェ曲線</h4>
<canvas id="canvas4" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas4");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// キャンバスの原点に移動
	cx.moveTo(0,0);
	// ベジェ曲線を描画
	cx.bezierCurveTo(0,100,100,0,100,100);
	// 線を書き出し
	cx.stroke();
//--></script>
arcTo()
<h4>arcTo()</h4>
<canvas id="canvas5" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas5");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// キャンバスの原点に移動
	cx.moveTo(0,100);
	// 直線と円弧を描画
	cx.arcTo(25, 25, 100, 100, 25);
	// 線を書き出し
	cx.stroke();	
//--></script>
円弧
<h4>円弧</h4>
<canvas id="canvas6" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas6");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// 時計回りで円弧を描画
	cx.arc(50,50,25,0, (90 * Math.PI / 180), false);
	// 線を書き出し
	cx.stroke();	
//--></script>

ラジアン表記で計算させます。
「度数 × π / 180」rad

<h4>円</h4>
<canvas id="canvas7" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas7");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// 半径25ピクセルの円を描画
	cx.arc(50,50,25,0,2 * Math.PI, true);
	// 線を書き出し
	cx.stroke();	
//--></script>
扇形
<h4>扇形</h4>
<canvas id="canvas8" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas8");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// パスをリセット
	cx.beginPath();
	// (50,50)を扇形の中心とする
	cx.moveTo(50,50);
	// 半径25ピクセルの円を描画
	cx.arc(50,50,25,0,90 * Math.PI / 180, false);
	// パスを閉じる。円弧の終点から中心まで直線が自動で引かれる。
	cx.closePath();
	// 線を書き出し
	cx.stroke();	
//--></script>

サンプル3 - いろいろな線

グラデーション

キレイなグラデーションを描くことが出来ます。

線形グラデーション
<h4>グラデーション</h4>
<canvas id="canvas9" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas9");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// 線形グラデーションを作成
	var g = cx.createLinearGradient(0,0,200,0);
	// 始点に白、終点に黒を指定
	g.addColorStop(0,"white");
	g.addColorStop(1,"black");
	// 塗りつぶしのスタイルとしてグラデーションをセット
	cx.fillStyle = g;
	// 四角形を塗りつぶし
	cx.fillRect(0,0,200,200);
//--></script>

cx.createLinearGradient();で線形グラデーションを描きます

円形グラデーション
<h4>円形</h4>
<canvas id="canvas10" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas10");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	// 円形グラデーションを作成
	var g = cx.createRadialGradient(90,90,0,50,50,200);
	// 始点に白、終点に黒を指定
	g.addColorStop(0,"white");
	g.addColorStop(1,"black");
	// 塗りつぶしのスタイルとしてグラデーションをセット
	cx.fillStyle = g;
	// 円を書いて塗りつぶす
	cx.arc(100,100,50,0,2 * Math.PI,true);
	cx.fill();
//--></script>

cx.createRadialGradient();で円形グラデーションを描きます。
サンプル4 - グラデーション

画像のクリッピング

数行のJSを書くだけで、ページトップの画像を描くことが出来ます。

<h2><a name="clip">画像のクリッピング</a></h2>
<canvas id="canvas11" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas3 = document.getElementById("canvas11");
	// 描画コンテキストを取得する
	var cx3 = canvas3.getContext("2d");
	// クリッピング領域を指定
	cx3.beginPath();
	cx3.arc(250,60,40,0,2 * Math.PI,true);
	cx3.arc(90,120,40,0,2 * Math.PI,true);
	cx3.clip();
	
	// 画像の描画
	var image3 = new Image();
	image3.onload = function() {
		cx3.drawImage(image3,0,0,canvas3.width,canvas3.height);
	};
	image3.src = "canvas_image.jpg";

//--></script>

サンプル5 - 画像のクリッピング
切り抜き領域をしていすることがポイントです。
時間の経過で、クリッピング領域を変化させれば、スポットライトのような動きができそうです。

テキストの描画

<h2><a name="char">テキストの描画</a></h2>
<canvas id="canvas12" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas12");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	var message = "蛇田.jp";
	var textHeight = 32;
	cx.font = textHeight + 'px "ヒラギノ角ゴ Pro"';
	// 表示するテキストの幅を取得する
	var textWidth = cx.measureText(message).width;
	// テキストの背景を描画
	cx.fillStyle = "pink";
	cx.fillRect(0,0,textWidth,textHeight);
	// テキストを描画
	cx.fillStyle="black";
	cx.textBaseline = "bottom";
	cx.fillText(message,0,textHeight);
//--></script>

<canvas id="canvas13" width="300" height="200"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas = document.getElementById("canvas13");
	// 描画コンテキストを取得する
	var cx = canvas.getContext("2d");
	cx.fillText("hebita164",30,30);
	// 拡大
	cx.scale(2,1.5);
	cx.fillText("hebita164",30,30);
	// 拡大を元に戻す
	cx.scale(1 / 2, 1 / 1.5);
	var angle = 20 * Math.PI / 180;
	// 回転
	cx.rotate(angle);
	cx.fillText("hebita164",30,30);
	// 回転を元に戻す
	cx.rotate(-angle);
	
	// 移動
	cx.translate(50,50);
	cx.fillText("hebita164",30,30);
	// 移動を元に戻す
	cx.translate(-50,-50);
//--></script>

サンプル6 - テキストの描画
傾けたテキストの表示ができるのがとても魅力的です。

画像のエフェクト

<h2><a name="mirror">画像のエフェクト</a></h2>
<canvas id="canvas14" width="600" height="675"></canvas>
<script type="text/javascript"><!--
	// canvas要素のDOMオブジェクトを取得
	var canvas4 = document.getElementById("canvas14");
	// 描画コンテキストを取得する
	var cx4 = canvas4.getContext("2d");
	// クリッピング領域を指定
	//cx4.beginPath();
	
	// 画像の描画
	var image4 = new Image();
	image4.onload = function() {
		// 画像を描画

		cx4.drawImage(image4,0,0);
		// 画像を半透明にし、画像を反転させて描画
		
		cx4.globalAlpha = .3;
		
		cx4.transform(1, 0, 0, -0.5, 0, image4.height * 1.5);
		
		cx4.drawImage(image4,0,0);
		
	};
	image4.src = "canvas_image.jpg";

//--></script>

サンプル7 - 画像のエフェクト
鏡で反転した効果を掛けることができます。

ご指摘等ありましたらtwitterでご連絡いただければと思います!

参考書

HTML5&API入門

HTML5&API入門

リンク

  1. HTML5 基礎知識 - HTML5の基礎知識
  2. HTML5 canvas関連API - 本エントリーで取り上げているAPIの解説や使い方
  3. canvas サンプル集 - 本エントリーで取り上げているcanvasのサンプル