円弧をループさせてたスクリプトをアップデートした

1月半ばから3週間の休暇を経て復帰しました。Araiです。
本当は休み1週目のブログ当番に当たっていたのですが、延期していただいていました。
休み中は特に何もしていなかったのですが、自分で作ったjQueryプラグインのブラッシュアップやjsdo.itに上げているコードの手直しをしていました。

そんなわけで以前書いたスクリプトを以下のようにアップデートしました。

(ちょっと古めのノートPCに入ってるChrome 24では1FPSも出てなかったので閲覧注意。
Macなどそんなに古くないデスクトップやiPhone 4S iOS6なら問題ない速度が出ていました)

アップデートした部分はアニメーションをsetIntervalからrequestAnimationFrameに変更したのと、FPS表示機能を追加した部分です。

requestAnimationFrame

requestAnimationFrameの設定の仕方は大体こんな感じです。
ブラウザごとに実装が違うので、ベンダープレフィックス付きのメソッドを返す必要があります。
requestAnimationFrameに対応していないブラウザにはsetTimeoutでアニメーションさせます。

var requestAnimFrame = (function() {
  return window.requestAnimationFrame  ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame    ||
    window.oRequestAnimationFrame      ||
    window.msRequestAnimationFrame     ||
    function( callback ){
      window.setTimeout(callback, 1000 / 60);
    };
}());

実行の仕方は以下の通り。
setTimeoutでアニメーションさせる時と同じように自分自身を呼び続けます。

var process = function() {
  //ここに処理内容を書く
  requestAnimFrame(process);
};

setInterval / setTimeoutのアニメーションとrequestAnimationFrameのアニメーションの違いは以下の通りです。

  • 前者は時間を基準に更新を行うが、後者はブラウザが描画処理を行う準備が整ったら随時更新を行う
  • 前者はタブがバックグラウンドでも動き続けるけど、後者はバックグラウンドだったら処理がストップするのでよりエコ(消費電力的な意味で)
  • 後者は更新のタイミングがブラウザ依存なので、時間で制御するのがちょっと難しい
    • なぜrequestAnimationFrameを使うのかというと、モニタの描画更新のタイミングが16.7ミリ秒(60FPS)らしく、前者の実装で4ミリ秒で更新するアニメーションを行うとコマ落ちしてしまいスムーズなアニメーションができなくなるので、ブラウザ側で更新を管理してくれる後者を使った方が滑らかなアニメーションを実現できるからだそうです。
      前者は上述のようにバックグラウンドでも動き続けるなどビミョーな点があったのですが、バックグラウンドになった場合は自動的に1000ミリ秒で更新するようなブラウザ側の実装になったようで、適切に使えば後者を使わなくても前者で事足りるのではないかとも言われています。

      その辺は以下のページも読んで参考にしてください。

FPS

こちらはぼーっとGithubを眺めていたらおもしろそうなコードがあり、FPS表示ってこうやって実装するのか!と知ったので組み込んでみようと考え拝借しました。

var FPSCheckPoint = new Date();
var getFPS = function() {
  var now = new Date();
  var fps = 1000 / (now - FPSCheckPoint);
  FPSCheckPoint = now;
  ctx.font = ('18px sans-serif');
  ctx.fillStyle = 'black';
  ctx.fillText(fps.toFixed(1), 18, 36);
};

こんな感じの関数を作り、以下のようにrequestAnimationFrameの関数の中で実行すれば値が更新され続けます。

var process = function() {
  getFPS();
  requestAnimFrame(process);
};

たまに100FPSとかになりますが、大体60FPSあたりの値が出ます。

勉強して新しいことを知ることは楽しいなと感じます。
まだまだJavaScriptの書き方でイケてない部分も多いのですが、以前書いたスクリプトを見ると自分の中では日々進歩している感があるのでもっと勉強してもっと良いコードを書けるようになりもっと色々出来るようになりたいと思っています。

「円弧をループさせてたスクリプトをアップデートした」への1件のフィードバック

コメントは停止中です。