RequestAnimationFrameを使う
かつて、アニメーションを伴った描画を行う際、setTimeoutやsetInterval関数を使って時間間隔をあけ、グラフィクスを更新していました。ところがこれらの関数は、ディスプレイのリフレッシュレートとは無関係に呼ばれるため、しばしば高負荷な状態となり、固まってしまうこともありました。こうした問題に対して、RequestAnimationFrameという解決策が提示されました。これは、リフレッシュレートをみながら最適なタイミングで描画処理を促すことができる方法です。この手法を用いるとCSS TransitionやSVG Animationなど、複数のアニメーションを動かす場合でも再描画タイミングが同期され、ずれるようなことが起こりにくくなります。
また、タブが裏に回ったときやウィンドウが最小化状態のときのように、アニメーションを含むコンテンツが非表示の場合は、再描画が促されなくなることも大きなメリットです。FirefoxではmozRequestAnimationFrameというメソッドを呼ぶことで、指定したfunctionがアイドル状態になったときに呼ばれるようになります。同様のメソッドは、webkit系ブラウザ(Google Chrome、Safari)、Opera、IE10でも実装されています。なお、本修正をProcessing.jsに入れ込むことも可能で、ここで利用しているprocessing-1.2.3.jsは、すでにその修正が入っています。
以下のコードは、オリジナルのprocessingの実装と、RequestAnimationFrameを使うように施した例の違いです。
var executeSketch = function(processing) { // Don't start until all specified images and fonts in the cache are preloaded if (!curSketch.imageCache.pending && curSketch.fonts.pending()) { //割愛 } else { window.setTimeout(function() { executeSketch(processing); }, 10); } }; // The parser adds custom methods to the processing context // this renames p to processing so these methods will run executeSketch(p);
//利用可能な RequestAnimationFrame を探す var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ //見つからなかったので、既存のやり方で window.setTimeout(callback, p.curMsPerFrame); }; var processing = p; var executeSketch = function() { // Don't start until all specified images and fonts in the cache are preloaded if (!curSketch.imageCache.pending && curSketch.fonts.pending()) { //割愛 } else { requestAnimationFrame(executeSketch); } }; // 次のフレーム再描画まで待って関数を実行 requestAnimationFrame(executeSketch);
今回のまとめ
今回は主にCanvas周りの描画に注目し、Canvasへの直接的な描画やProcessing.jsを利用した描画、アニメーションの作成方法やFlashとのコードの比較などを解説しました。例に挙げた通りCanvasによって自由な描画やアニメーションが作成が可能となったことに加え、ウェブ標準となったこともあり、今後益々利用されていくことが予想されます。
次回は、CSSやSVG、Audio Data APIなどに触れたいと思います。