2010年04月04日

HTML5のCanvasでエフェクトアニメーションを作る

今回はHTML5のCanvasエレメントで波紋が動くエフェクトを作る実験だ。

Canvas Wave
Canvas Wave Image
Show me
/ Download

このデモでは、画像の適当な場所をクリックすると、そこを中心に波状のエフェクトアニメーションが動き出す。
CPUパワーを使いすぎないように描画間隔を調整しているので、処理が重すぎてハングアップすることはない。はず。

処理の流れ

まず、Canvasの画像をgetImageDataでImageDataオブジェクトに変換して、そのピクセルを直接いじって特殊効果をかけている。
効果をかけたImageDataをputImageDataでCanvasに書き戻す。
これをタイマーで適当に間隔をあけて繰り返すと、このサンプルのようなエフェクトができる。
フレームごとに400*267のピクセルを全部書き換えており、さらに1ピクセルごとに三角関数や平方根の計算をしたらどのくらいのスピードになるか。という、ベンチマークのために作ってみた。


Chrome 4.1: ○

FireFox 3.6.2: ○

Opera 10.51: ○

Safari 4.0.5: ○

上記の「モダンな」ブラウザでは問題なく動作する。
自前で直接ImageDataのピクセルを操作しているので、どのブラウザでも挙動に違いはない。
ただし、動作速度の違いがフレームレートに現れる。現状ではChromeが最も速く、滑らかなアニメーションになる。

IE 8.0: ×

IEは完全に非対応。現状のExplorerCanvasはgetImageData/putImageDataをサポートしていないので動かしようがない。ExplorerCanvasが使っているVMLには該当する機能がないようなので、今後もサポートされる見込みは薄い。


今回のまとめ

というわけで、CanvasのImageDataを使って直接ピクセルをいじって描画すると、互換性はあまり気にならない。
各ブラウザでJavaScriptの速度が向上しているので、アニメーションを行っても十分に実用的なフレームレートが出せる。
パフォーマンスでは専用ハードウェアを活用したバイナリコードに及ばないけれど、理屈の上では3Dだろうが動画のデコードだろうがなんでもできる可能性がある。
ただし、IEは完全に蚊帳の外だ。残念ながら、IE9でさえCanvasをサポートしないので動かせない。
現状でWebサービスでIEを除外するのは現実的ではないので、「あってもなくても困らないエフェクト」くらいしか使えない気はする。
しかし、ImageDataは表現の幅を飛躍的に高める可能性を秘めているので、捨てるにはもったいなすぎる。もっと面白い使い道を考えていきたい。

posted by lislis at 14:46| Comment(0) | TrackBack(0) | HTML5

2010年04月03日

HTML5のCanvasエレメントで時計を作る

HTML5のCanvasエレメントの勉強のために時計を作成してみた。

Canvas Clock
Canvas Clock Image
Show me
/ Download

Canvasを使った時計ならすでにあるけれど、今回のデモでは
  1. イメージソースとして透過PNGを使用。
  2. 画像の読み込み中にLoading画面を表示。
  3. 針の影を表示。

と、若干の手間が入っている。
これだけのことで、後述のように、ブラウザによってずいぶんと動作に違いがでてくる。


Opera 10.51: ○

このデモに関してはOperaが一番の優等生で、期待通りに動作する。このページに貼った画像はOperaでの実行画面をキャプチャしたものだ。

Safari 4.0.5: ○

期待通りの描画結果になる。ただし、Windows版で試したせいか非常に重い。

Chrome 4.1: △

Chromeでは針の影が描画されない。drawImageしたときに影がでないらしい。また、描画精度の問題か、針の表示位置が微妙にずれてガクガクする。

FireFox 3.6.2: △

FireFoxはfillTextが未実装のようで、文字が描けない。

IE 8.0: ×

IEはCanvasエレメントがないので、これをVMLでエミュレートするExplorerCanvasを使ってみた。しかし、それでも正常に表示されない。
ロード中の丸表示や時計の目盛など、lineToで描いている部分だけは問題ないのだけれど、fillTextで文字を書く部分が動作しない。
さらに、画像が表示されなかったり、変なサイズで変な位置に表示されたり、透過PNGの半透明部分が不透明になったりする(アルファが0か1の2値になってしまう)。


このように、現時点ではこれだけのデモでも互換性の問題が多発する。

posted by lislis at 11:12| Comment(0) | TrackBack(0) | HTML5