- 2012年02月02日 (木)
- Tweet
HTML5 Canvasを始めよう:EaselJSとTweenJSでテキストエフェクト
HTML5のCanvasをFlashライクに使えるようにするJavaScriptライブラリ「EaselJS」と「TweenJS」を使ってデモを作ってみました。
今回のブログ記事では「EaselJS」と「TweenJS」の使い方をデモの作り方を通して紹介します。
ライブラリの紹介
「EaselJS」と「TweenJS」はFlashのエンジニアとして著名なGrant Skinner氏が開発しているJavaScriptライブラリです。「EaselJS」がHTML5 CanvasをFlashライクに使うためのライブラリで、「TweenJS」が汎用的なトゥイーンライブラリです。
HTML5のCanvas要素はHTML上に自由に描画することのできる新しい要素で、工夫することでFlashのように豊かな表現を作ることができます。ただCanvasではJavaScriptでちょっと癖のある記法を使うことになるので、学習コストを下げる&生産性を上げるためにもCanvasをFlashライクに使うことのできるEaselJSが注目されています。
デモの作り方
冒頭のデモですが、twistcubeさんのFlashの作品「SliceEffect」(wonderfl)から移植したものです。短いスクリプトの中に動きや実装のテクニックが詰まっていますので、ぜひオリジナルの作品のほうもチェックしてみてください。
さて、このデモをHTML5 Canvasに展開するにあたり、特に抑えておきたいのは次の点だと思いました。
- 画像の一部分のキャプチャ
- 画像の表示オブジェクトへのインスタンス化
- トゥイーンの適用
- エンターフレームイベントの実装方法
これらを詳しく解説していきます。
画像の一部分のキャプチャ
▲もとの画像ファイル「text.png」
スライスエフェクトを実装するにあたり、画像を横幅1pxの短冊状に分割する必要があります。そのためにダミーのCanvas要素を用意しました。Canvas要素はFlashでいうところのBitmapとBitmapDataとShapeをごちゃまぜにしたようなHTML5の新要素です。BitmapDataのように描画したものをキャプチャする機能が曲りなりにもあるので、これを利用します。Canvas要素はbodyタグに追加(appendChild)しなくても機能するので、スクリプト上でダミーのCanvasのインスタンスを作成しておきます。
var dummyCanvas = document.createElement("canvas"); dummyCanvas.setAttribute("width", 1); dummyCanvas.setAttribute("height", image.height); var context = dummyCanvas.getContext("2d");
次に画像を短冊状に分割します。drawImage()メソッドはFlashで言う所のBitmapData.draw()のようなメソッドです。画像の一部分だけをトリミングして Canvasに描画することができます。そして描画したものを配列に保存します。Canvas要素のtoDataURL()メソッドを使えば描画結果を画 像データとして取得することができます。ここではループ文を使って、画像の左端から右端まで1px毎にこの処理を繰り返して結果をPNGデータとして配列 に保持しておきます。
var srcArr = []; for ( var i = 0; i < image.width; i++ ){ context.drawImage(image, i, 0, 1, image.height, 0, 0, 1, image.height); srcArr[i] = dummyCanvas.toDataURL("image/png"); }
画像の表示オブジェクトへのインスタンス化
次に画面に表示する表示オブジェクトの作成です。EaselJSにはShapeやBitmap、TextなどFlashのクラス名に似た表示クラスが用意されています。今回は上の手順で作成した画像リソースを使いたいので、Bitmapクラスを利用します。次のようにしてBitmapインスタンスを作成し、XY座標や透明度を設定したうえで、stageにaddChild()します。addChild()するあたりはActionScript 3.0とそっくりですね。
var bmp = new Bitmap(srcArr[i]); bmp.x = centerX + 1000 * Math.random() - 500; bmp.y = centerY + 1000 * Math.random() - 500; bmp.alpha = 0; stage.addChild(bmp);
▲表示オブジェクト関連のJSクラス。Flashのflash.dislplayパッケージのようなクラスが用意されています。
トゥイーンの適用
画面に表示したら次は動きを実装します。ActionScriptで作る場合はTweenerやBetweenAS3、Tween24などのライブラリを使ってトゥイーンを作っていたと思います。それと同様に、JavaScriptでもトゥイーンを作ることのできるライブラリがあるのでそれを利用します。EaselJSと相性がいいのは同作者が開発しているTweenJSです。TweenJSでは次の記述でトゥイーンを実装します。
Tween.get(bmp) .wait(1.5 * i + 1000) .to({ alpha : 1, x : centerX + i, y : centerY}, 1500, Ease.elasticOut);
メソッドチェーンで処理を書く感じです。ActionScriptでトゥイーンをかじったことのある人ならなんとなく意味がわかると思いますが、ここではBitmapインスタンスに対して、ディレイをかけたうえで、透明度とXY座標を1.5秒でトゥイーンするようにしています。イージング方式をEase.elasticOutにしているのは演出の都合上です(勢い良くスライスが動いて見えるのはこのイージング方式によるところが大きいです)。
エンターフレームイベントの実装方法
最後にレンダリングを設定します。EaselJSの仕組みですが更新するときにはレンダリングメソッドのupdate()を実行します。EaselJSのTickerというクラスがエンターフレームイベントを管理するようになっていますので、次の記述でレンダリングメソッドを呼び出すようにします。
Ticker.setFPS(60); Ticker.addListener(window); function tick(){ stage.update(); }
最後に
HTML5 CanvasはFlash Player 7.5ぐらい (Flash Player 8のBitmapData系の機能を一部実装したようなFlash Player 7という意)なので、Flashと比べると実現できることはまだまだ少ないのが現実です。ただ、実現できることは少なくてもレガシーなFlash(3〜5)の時代に様々な表現が試されたように、工夫次第で表現は作ることができます。EaselJSを使えば学習コストを抑えてHTML5 Canvasを試すことができるので、挑戦してみてはいかがでしょうか?
今後の予告ですが、EaselJSとTweenJSを使ってHTML5 Canvasのデモをいくつか作成してみましたので、しばらくはこれらをブログで紹介していきたいと思います。
▲テキストのフラクタル
▲パーティクルの流体表現
2012年02月06日(月) 13:05
こちらの記事ではないのですが、shuffleElementTxt(http://clockmaker.jp/labs/120203_html5_shuffletext/dom.html)でpにdata-indexの連番を付与するテクニックですが、なぜそれをしているのか理由を教えていただけませんでしょうか?><
2012年02月06日(月) 17:07
takuさん、コメントありがとうございます。
data-indexを使っている理由ですが、マウスオーバー時に配列の何番目の要素に対してエフェクトを再生するべきか情報を保持するためです。
他にもいい方法があるかもしれませんが、Flash(ActionScript 1.0/2.0)のときは要素毎にdata-indexのようなプロパティーを持たせて処理することが多かったので、同じような方法を適用した次第です。
2012年02月06日(月) 18:27
かつてのmc.name=連番 的なイメージですね!
ありがとうございました!