まだまだ間に合うCanvasでアニメーション入門(まとめと実践)

JavaScript Advent Calendar 2010も22日目!あと3日ですよ。僕はちょうど学んだばかりのCanvasをアウトプットもかねて、まとめと実践を書いてみます。知ることと行うことは同一である、最近行ったセミナーでも言ってました。

jsdo.itにはほんまにこれCanvasなん?なサンプルいっぱいありますね。あーいうの書けるようになりたいなぁとか思いつつ、jQueryばっかりさわってた僕は.animate()メソッドの便利さに取り憑かれていたので、Canvasの絵もまだ上下左右で動かすくらいしかできません。慣れが必要です。。

どうでもいい情報としてCanvasの読み方なんですけど、「キャンバス」じゃなくて「カンバス」が正しいようです。キャンバス・カンバスどっちでもよさげ。僕はキャンバスって読んでましたけどカンバスにします。

前置きはこれくらいにして、今回は次のようなカラフルな箱が延々と落ちていくっていうのを書いてみます。今回のサンプルはすべてCanvasなのでIE8以下だと見れないと思います。あとjsdo.itのサンプルをいくつか貼っているのでRSSだと表示されません

先に参考サイト紹介してますが、いらない人は飛ばしてください。レッツカンバス!

参考サイトなど

動かす前に、そもそもCanvas自体さわったことがなかったので色々調べもってやってみました。とりあえずこれから始める人も多いと思うのでお世話になったサイトあげておきますね。あーこんな風にね的な。

HTML5.jpのCanvasページ

Canvasの超基本。メソッドのリファレンスはこっち

今更聞けないcanvasの基礎の基礎

とりあえず見とくエントリー。ボールが弾むやつとか全然理解できませんでしたけどね!

canvasでキラキラした背景を作る方法

アイデアって大事ですよね

なかにしさんのサンプルは最初に見るのにちょうどいい

canvasで遊んでみたい【その1その2その3その4その5】まであります
とりあえず星空描いてみましょうか

canvasでアニメーションする時のコツ

僕がアニメーションやるっていうときに最初に見たんですけどさっぱりでした。後からみて納得

JS + Canvas = 3D しました

3Dもできるようになりたいです・・・

Canvasで実現するカラフルな円が小さくなったり大きくなったりする背景

これも超参考にしました。重なるとことかどうなってるんかなーとか。

[HTML5 canvas] 簡単な 3D アニメーション

こんな感じにXYZ座標をあやつりたい・・・

HTML5 Canvasのブラウザによって異なる微妙な振る舞いについてまとめてみた。

ブラウザによって描画され方がちがうらしいです。気にしておかないとだめですね。

canvasが手軽にウェブで試せるアプリFirstCanvasを作ったよ

Canvasだけならjsdo.itよりもお手軽に試せます

実際になんか書いてみる

参考サイト見てテンションがあがったところで、早速実践です。

HTMLで用意するのはこれだけです。今回ソースコードの表示とサンプルにjsdo.itを利用してるので、フォークしたりできます。

まずはかく

さーさーなんか書いてみましょう!お約束の矩形描画です。これは簡単。

とりあえずうごかす

次は描いた矩形を少し動かしてみましょう。最初は簡単にsetTimeoutでいいでしょう。最初の矩形を描いたあとに、Canvas全体を塗りつぶし、その後位置をずらしてもう一度矩形を描画しているだけです。

くりかえしうごかす

つまりこれを繰り返せば動くんじゃ・・・的な発想ですね!間違ってないと思います。上から下まで動かしてみましょう。

アニメーションできた・・・!これがアニメーションといえるのかどうか・・・でも動いてるからいいでしょ。最初はこんなもんです。

アニメーションのポイント

アニメーション自体はsetIntervalで繰り返すことでも行えますが、ここでは

(function() {
  // hogehoge
  setTimeout(arguments.callee, 1000 / rate);
})();

というような書き方で実行しています。これをsetIntervalで書き直すとこんな感じ

setInterval(function() {
  // hogehoge
}, 1000 / rate);

無名関数で実行するときは、// hogehoge の部分が終わってからsetTimeoutが呼ばれるのに対して
setIntervalは // hogehoge が終わっていなくても 1000 / rateミリ秒後にもう一度 // hogehoge が実行されます。

もうひとつの違いはタイマーのクリア方法です。無名関数は関数内でreturn false;するだけなのに対して、setIntervalはタイマー変数をclearIntervalする必要があります。

無名関数

(function() {
  if ( fuga ) return false;
  // hogehoge
  setTimeout(arguments.callee, 1000 / rate);
})();

setInterval

var timer = setInterval(function() {
  if ( fuga ) clearInterval(timer);
  // hogehoge
}, 1000 / rate);

ここはその内僕が書くかもしれないし、誰かが書いてくれるかもしれないし、難しいことは考えずにとりあえずはどちらでもよいでしょう。

つづき:アニメーションのループ

次は下まで降りていったらまた上からでてくるようにしてみましょう。簡単です。

複数同時にうごかす

なんか上から下まで落ちるブロックみたいなんできました。数を増やして色もランダムにしてみましょう。難易度がいきなりあがる感じです。とりあえず同じタイミングで矩形を10個描いて落下させます。

複数個の矩形を描いて動かす

矩形がひとつと複数個あるでは対応の仕方が全然違います。ひとつの場合は、fillRectが一回だけでよかったのに対して複数個描画する場合は、その個数回fillRectする必要がありますし、個数分の矩形情報が必要です。

矩形情報の生成に Box()という関数を用意しました。

// 新しい矩形を生成する
var Box = function() {
  // サイズ、移動速度、横座標の位置、色はランダム
  this.size = randomNum(20, 10);
  this.speed = randomNum(5, 2);
  this.color = 'rgba(' + randomNum(255) + ',' + randomNum(255) + ',' + randomNum(255) + ',' + .6 + ')';
  this.basePos = {
    x: randomNum(300),
    y: 0
  }
}

ちなみにランダムな数を返す関数を作っておくと便利に使えます。

// 最小〜最大の間でランダムな数値を返す
// 最小値を省くと1〜最大値の間でランダムな数値
function randomNum(maxInt, minInt) {
  var ran = Math.random();
  if ( minInt ) {
    if (Math.floor(ran * maxInt) < minInt ) {
      return minInt;
    } else {
      return Math.floor(ran * maxInt);
    }
  } else {
    return Math.floor(ran * maxInt) + 1;
  }
}

いままではひとつだけの矩形でしたが、10個の矩形を扱います。単純にboxPoolという配列を用意して、そこに矩形の情報をつめこんでおきます。

// 矩形を生成しておく(描画はまだ
for ( var i=0; i
            

あとは矩形の個数回fillRectするだけです。

// 矩形毎に描画していく
for ( var i=0; i
            

完成:複数の矩形を動かしてループ

落ちるだけだったので、最後にループさせて完成っぽいですね。仕組みは、さっきのループを応用します。矩形がcanvas外に出たら外にでた矩形を削除して、新しく矩形を生成します。つまりこれを繰り返し行うだけです。56行目〜80行目が追加・修正した部分です。

特に重要なのは56〜61行目、canvas外に出た矩形情報を取り除くところ

// 矩形がcanvas外に出たら一旦削除する
if ( thisBox.basePos.y > canvas.height ) {
  boxPool.splice(i--, 1);
  boxLen--;
  continue;
}

76〜80行目の10個以下になった場合は矩形情報を新規で追加するところでしょう。

// 矩形の数が10個以下であれば
// 新しい矩形を生成する
if ( boxPool.length < 10 ) {
  boxPool.push(new Box());
}

おわり

ちょっと駆け足でしたが、Canvasを使ったアニメーションが書けました。なんでもやってみることが重要です。やってみないことには先に進まないので、少しずつでもやってみてバリエーションが増えてくれば、そのうちぐりぐり動かせるようになるんじゃないでしょうか。インプットの先のアウトプットまでできればなおいいですね。

何か役に立つことがあったらシェアしてみてください

このエントリーをはてなブックマークに追加

Leave a comment

Trackbacks: 0

Trackback URL for this entry
Listed below are links to weblogs that reference
まだまだ間に合うCanvasでアニメーション入門(まとめと実践) from 5509

Author

nori
nori
- UI Engineer
Location
- ,