WEBOPIXEL

HTML5で作るCanvasアニメーションの基礎

Posted: 2015.07.10 / Category: javascript / Tag: 

HTML5のCanvasを使用して簡単なアニメーションを作成してみます。

Sponsored Link

円を描画する

アニメーションさせる為にはなにか物が必要なので、とりあえず円を描いてみましょう。
HTMLにcanvasタグを作成し、適当なidを割り当てます。

<canvas id="canvas-container" width="600" height="300"></canvas>
    

次はJSです。

window.onload = function() {
    // Canvas未サポートは実行しない
    if (!window.HTMLCanvasElement) return;
    var canvas = document.querySelector('#canvas-container');
    var ctx = canvas.getContext('2d');

    // 円の描画
    ctx.beginPath();
    ctx.arc(100, 100, 20, 0, 2*Math.PI, false);
    ctx.fillStyle = '#D0A869';
    ctx.fill();
};

arcの第一引数がXの位置、第2引数がYの位置、第2引数が大きさになります。

Canvasの基本的な描画に関しては下記の記事も参考にしてください。

html5のcanvasで簡単な図を描いてみた

ループアニメーションの準備

アニメーションに興味がある方ならば、ぱらぱらマンガは描いたことがあると思います。 あれは絵を少しずつ変化させて、ぱらぱらめくることでアニメーションを表現していました。
Web上のアニメーションも基本的な考え方は同じで、例えば移動させたい場合は位置をすこしずつ加算して描画・削除を高速に繰り返すことでアニメーションを表現します。

ということはアニメーションを表現する為には同じ関数を連続で実行する仕組みを作る必要があります。
JavaScriptではsetIntervalを使用することで簡単にループ処理を作成できますが、最近ではrequestAnimFrameが推奨されています。

requestAnimFrameはベンダープレフィクスなどを記述しないといけなかったり、サポートしていないブラウザも考慮する必要がありますので、そのまま使用しないで下記のようにします。

window.requestAnimFrame = (function(){
	    return  window.requestAnimationFrame   ||
	        window.webkitRequestAnimationFrame ||
	        window.mozRequestAnimationFrame    ||
	        window.oRequestAnimationFrame      ||
	        window.msRequestAnimationFrame     ||
	        function(callback){
	            window.setTimeout(callback, 1000 / 60);
	        };
	})();

後述するループ処理の部分で「requestAnimFrame(loop)」として使用します。

引用元:requestAnimationFrame for Smart Animating

先ほどの円の描画コードもわかりやすくする為、関数化しておきましょう。

    function drawCircle(x, y, scale, color) {
        ctx.beginPath();
        ctx.arc(x, y, scale, 0, 2*Math.PI, false);
        ctx.fillStyle = color;
        ctx.fill();
    }

下記のように一行で書けるようになりました。

drawCircle(X座標, Y座標, サイズ, カラー);

作成したrequestAnimFrameとdrawCircleを組み合わせて、ループ部分の関数(loop)を作成してみましょう。

loop();

// ループ処理
function loop() {
    requestAnimFrame(loop);
    // 描画をクリアー
    ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);
    // 円を描画
    drawCircle(100, 100, 20, '#D0A869');
}

これでloop関数が連続で実行されている状態になります。
でもdrawCircleの位置の部分が固定になっているので動きませんね。

水平方向の移動アニメーション

水平方向のアニメーションはX座標の数値を変化させることでできます。

新たに、X座標(x)と速度(speed)を入れる変数を作成しましょう。
あとはループ関数にxにspeed分だけ加算していけば水平方向の移動ができます。

var speed = 2;    //移動速度
var x = 0;      //X軸の位置

// ループ処理
function loop() {
    requestAnimFrame(loop);
    ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);
    // ループ毎にxを加算
    x += speed;
    // 円を描画
    drawCircle(x, 100, 20, '#D0A869');
}

このようにX座標に同じ値を加算し続けることで、一定の速度で水平方向で移動することができます。
縦に動かしたいときは第2引数のY座標を変動させればできますね。

目的地点を決めて移動

次はある地点まで移動するというアニメーションを作成します。
これは下記の計算式を使用することでできます。

(目標地点 – 現在の位置) / 速度

9行目の「x += speed;」を上記の式に置き換えてみましょう。
speed変数は少ないと早すぎるので調節しましょう。

x += (400 - x) / speed;

アニメーションの本当に基礎の部分ですが以上です。
ここから発展することできっと色々なことができそうな気がします。