html5のCanvasを使ってアニメーションを作る3

前回のおさらい

第2回では、変数や関数を使いコードを改善してみました。
現在のコードでは、ブラウザでページを開くと M という文字が右斜め下に位置をずらしながら増加していきます。

c6

これを、M が右下に動くようにアニメーションにしてみます。

アニメーションとは

Canvas のアニメーションは、以下の繰り返しです。

1. Canvas に描画されているものを一旦クリアする
2. 描画するものの状態(座標や動く距離)を更新する
3. 描画する

今のコードの場合、2 と 3 は実装されていますが、1 がありません。
1 を実装することで、一つの M という文字が動いているように見えます。

1 の実装は簡単で、以下を animate 関数の初めに追加します。

ctx.clearRect(0,0,canvas.width,canvas.height);

clearRect は、引数で指定した範囲の描画をクリアします。
詳細は Google などで検索下さい。

コードは以下のようになります。

var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
 
var x = 50;
var y = 50;
 
var velocityX = 10;
var velocityY = 10;
 
ctx.fillText('M', x, y); //初期位置の M を描画
 
//更新処理と描画処理を再利用できるように関数として定義する
function animate(){
 ctx.clearRect(0,0,canvas.width,canvas.height); //描画をクリア
 x = x + velocityX; //更新処理
 y = y + velocityY; //更新処理
 ctx.fillText('M', x, y); //描画処理
}
 
setInterval(animate, 200);

カクカクしているので、もっとなめらかにします。
setInterval(animate, 200); の部分を、setInterval(animate, 1000/60); にします。
これで、1秒間(1000ミリ秒)に60回描画することになります。

ただし、これだと動きが速すぎるので、velocityX と velocityY を 1 にします。
以下のようになります。

var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
 
var x = 50;
var y = 50;
 
var velocityX = 1;
var velocityY = 1;
 
ctx.fillText('M', x, y); //初期位置の M を描画
 
//更新処理と描画処理を再利用できるように関数として定義する
function animate(){
 ctx.clearRect(0,0,canvas.width,canvas.height);//描画をクリア
 x = x + velocityX; //更新処理
 y = y + velocityY; //更新処理
 ctx.fillText('M', x, y); //描画処理
}
 
setInterval(animate, 1000/60);

Canvas でアニメーションのまとめ

以上で、Canvas を使ったアニメーションの作成は終わりです。
本当に触りの部分だけですが、これが基礎になります。

個人的に大切だと思うのは、描画をクリア、更新する、描画する、のそれぞれの処理を分けて考えることです。
さらに本格的なアニメーションやゲームの場合、setInterval() ではなく requestAnimationFrame() を使い、

  • フレームレート更新
  • 描画をクリア
  • 背景を描画
  • 描画オブジェクトを更新
  • 描画オブジェクトを描画
  • 次のアニメーションフレームを要求

のようになると思います。
一度に考えると混乱しますが、一つ一つの処理を分けて考え、処理する順番を考えていけば、完成すると思います。

最後に全体のコードを記載しておきます。

<!doctype html>
<html lang="ja">
    <head>
        <title>Canvas 練習</title>
        <meta charset="utf-8">
        
        <style>
            #mycanvas{
                border: 1px solid;
            }
        </style>
        
    </head>
    
    <body>
        <canvas id="mycanvas" width="500" height="300"></canvas>
    </body>
    
    <script>
        
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
 
var x = 50;
var y = 50;
 
var velocityX = 1;
var velocityY = 1;
 
ctx.fillText('M', x, y); //初期位置の M を描画
 
//更新処理と描画処理を再利用できるように関数として定義する
function animate(){
 ctx.clearRect(0,0,canvas.width,canvas.height);//描画をクリア
 x = x + velocityX; //更新処理
 y = y + velocityY; //更新処理
 ctx.fillText('M', x, y); //描画処理
}
 
setInterval(animate, 1000/60);



    </script>
    
</html>