CreateJSとCanvas APIの比較
対象デバイスをPCに限定してFlashを活用したキャンペーンサイトなど特定の状況を除いて、スマートフォン/タブレット対応が求められる場合(大半がそうですが)、HTML5/JSでリッチなコンテンツを作成する機会が増えています。
Canvas APIではアニメーションを行うメソッドが提供されておらず、Canvas要素内でアニメーションを実現しようと思うと工数が増えてしまいがちです。
そこで、今後工数短縮の選択肢の一つとして検討出来るよう、CreateJS(EaselJSとTweenJS)とCanvas APIで同様の事を実現した際の違いを簡単に比較します。
CreateJSとは
HTML5のCanvas要素を使ってリッチなコンテンツを簡単に作成できるJavaScriptライブラリです。
次の4つのライブラリで構成されています。
- EaselJS
-
Canvas要素を効率的に扱うためのライブラリ。
通常のCanvas APIでは、簡単な図形を描くだけでも「直感的に扱える」とは言い難く、コードが長くなります。
EaselJSでは直感的に記述出来る事と、ActionScriptに似たAPIが実装されているため、Flashデベロッパーにも馴染みやすいようです。 - TweenJS
-
アニメーションを扱うためのライブラリ。
基本はCanvas要素に描画した図形等を簡単にアニメーション出来るといった機能(Flashで言うところのトゥイーン)ですが、CSSPluginを導入する事でHTML要素に対してもアニメーションが適用可能です。 - SoundJS
-
音声データを扱うためのライブラリ。
音声に関しては未検証ですが、実行環境によってAudio要素、Flash等を使い分けるようです。 - PreloadJS
-
外部ファイルの読込を制御するためのライブラリ。
名前の通り、ファイルのプリロードを行いますが、読込中や読込完了時に実行される便利なイベントがあります。
EaselJSとCanvas APIの比較
EaselJSで円を描いた場合と、Canvas APIで円を描いた場合のコードを比較します。
ただ円を描くだけであればコードの量はほぼ変わりませんが、EaselJSはAPIが直感的でわかりやすく、jQueryのようにメソッドチェーンで繋ぐことも出来ます。
- EaselJS
-
var stage = new createjs.Stage('canvas'); var circle = new createjs.Shape(); circle.graphics.beginFill('red').drawCircle(0, 0, 25); circle.y = 100; circle.x = 100; stage.addChild(circle); stage.update();
- Canvas API
-
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(100, 100, 25, 0, Math.PI*2, false); ctx.fillStyle = 'red'; ctx.fill(); ctx.closePath();
TweenJSとCanvas APIの比較
続いてTweenJS(Canvas要素に円を描く部分はEaselJS)を使ったアニメーションと、Canvas APIでのアニメーションを比較します。
Canvas APIの方は一部関数化しているのでコード量自体は大きく変わりませんが、TweenJSではAPIが汎用的かつ直感的なため非常に扱いやすい印象を受けました。
TweenJSのアニメーションは円(shape)を変数として参照して、プロパティ(位置・大きさなど)を更新する。
その後、stage.update()メソッドを実行して最新の状態をCanvas要素に描画する、といったシンプルな仕組みで実現されています。
一方Canvas APIでアニメーションを実現する場合は、リセット(円を描いた部分を背景色で塗り潰して消す)→少しずらして円を再描画→再リセットと延々繰り返すことでアニメーションを実現します。
一定速度で移動するアニメーションであれば苦労しませんが、円を複数描く場合や、アニメーションを滑らかにする(イージング)場合など、作るものが複雑になればなるほど設計が難しくなります。
- TweenJS
-
var stage = new createjs.Stage('world'); var circle = new createjs.Shape(); circle.graphics.beginFill('red').drawCircle(0, 0, 10); circle.y = 10; circle.x = 10; circle.speed = 5; stage.addChild(circle); stage.update(); createjs.Ticker.useRAF = true; createjs.Ticker.setFPS(30); createjs.Ticker.addEventListener('tick', function() { circle.x += circle.speed; if ( circle.x > 500 || circle.x < 0) { circle.speed *= -1 }; stage.update(); });
- Canvas API
-
var canvas = document.getElementById('world'); var ctx = canvas.getContext('2d'); var circleX = 10; var step = 5; drawCircle( circleX ); requestAnimationFrame( move ); function drawCircle( x ) { ctx.beginPath(); ctx.arc(x, 10, 10, 0, Math.PI*2, false); ctx.fillStyle = 'red'; ctx.fill(); ctx.closePath(); } function move() { circleX += step; ctx.fillStyle = 'white'; ctx.fillRect( 0, 0, 500, 500 ); if ( circleX > 500 || circleX < 0) { step *= -1; }; drawCircle( circleX ); requestAnimationFrame( move ); }
CreateJS(EaselJSとTweenJS)のデモ
これまでのサンプルコードは円を一つだけ描いていましたが、大量に描画してアニメーションさせます。
また、Canvas要素をクリックすると、クリックしたポイントに一旦集まってばらけます。
Canvas APIでこれだけの円を描画してアニメーションさせるのは苦労しますが、CreateJSを使えば100行程度のコードで実現出来ます。
また、円が集まる&ばらける際の時間やアニメーションは引数で容易に調整出来るなど非常に汎用性が高いです。
まとめ
- Canvas要素内でアニメーションを行うならCreateJSは汎用性が高く非常に実用的。
- 特に、図形を大量に描画する場合など図形が重なり合うケースで、各図形の状態管理(座標・大きさなど)をどうするか?等の設計を考えなくて良いので、本来作成したいコンテンツの作成に注力出来る。
- jQueryのイージングでもお馴染みですが、アニメーションを引数一つで変更出来るのは便利。