JavaScript:キャンバスでアニメーションする基本

JavaScript

canvasタグに描いた図形をアニメーションさせる基本です。
描画処理を関数化して再帰呼び出しが基本です。requestAnimationFrameメソッドを使うようにすると滑らかな描画が実現できます。

サンプルのソースコード

canvas_animation1.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,user-scalable=yes">
	<title>canvasでアニメーション</title>
	<script>
		let canvas, g;
		let y;

		function drawAnim(){
			// 画面をクリア
			g.fillStyle = "steelblue";
			g.fillRect(0, 0, canvas.width, canvas.height);
			// ●を描画
			g.beginPath();
			g.fillStyle = "khaki";	// 塗りつぶす色
			g.arc(250, y, 50, 0, Math.PI*2, false);
			g.fill();
			// アニメーションする
			y+=3;
			requestAnimationFrame(drawAnim);
			//setTimeout(drawAnim, 30); ←表示がカクカクする
		}

		window.addEventListener("load", ()=>{
			// キャンバスの初期設定
			canvas = document.getElementById("canvas");
			g = canvas.getContext("2d");
			// ●の初期y座標
			y = 0;
			// アニメーション開始
			drawAnim();
		});
	</script>
</head>
<body>
	<canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>

解説

起動時にキャンバス情報を取得しています。

// キャンバスの初期設定
canvas = document.getElementById("canvas");
g = canvas.getContext("2d");

塗りつぶし円をy方向に移動させるため変数yはグローバル変数として定義します。

let y;

描画処理は全て関数drawAnimにまとめました。これを起動時に呼び出します。

window.addEventListener("load", ()=>{
		:
		:
	// アニメーション開始
	drawAnim();
});

関数drawAnimの処理です。
背景に色をつけるため、clearRectではなくfillRectでキャンバス全体を塗りつぶしています。
キャンバスの幅と高さに具体的な500, 500という値を使うよりcanvas.width, canvas.heightを使った方がキャンバスのサイズを変えても対応できるので便利です。

// 画面をクリア
g.fillStyle = "steelblue";
g.fillRect(0, 0, canvas.width, canvas.height);

塗りつぶし円の描画では、y座標だけ変数を使って下方向に移動したように見せています。

g.arc(250, y, 50, 0, Math.PI*2, false);
		:
y+=3;

関数の最後でrequestAnimationFrameを使いdrawAnimを再帰呼び出しすることで、円を下方向に移動していくように見せてアニメーションを実現しています。

requestAnimationFrame(drawAnim);

requestAnimationFrameを使うと引数に指定した関数をディスプレイのリフレッシュレートにあわせて呼び出してくれます。大抵は60FPS(毎秒60回)となります。

setTimeoutという命令で一定時間後に再帰呼び出しもできますが、利用しない方が無難です。
試しにサンプルの requestAnimationFrame(drawAnim); の部分を           

setTimeout(drawAnim, 30);

と変更してみてください。
アニメーションはしますが、どこかカクカクとしてぎこちないものとなります。setTimeoutは、requestAnimationFrameと違いディスプレイのリフレッシュレートを考慮しないからです。

以上、JavaScript:キャンバスでアニメーションする基本でした。

コメント

タイトルとURLをコピーしました