[JS] アニメーションを行うのに、setTimeoutよりもrequestAnimationFrameを使ってみよう
こんにちは、@yoheiMuneです。
JavaScriptを用いてアニメーションを行う際に、setTimeoutやsetIntervalを使ってアニメーションループを実装することが多いと思いますが、 最近使えるようになってきたrequestAnimationFrameを使うと、よりいい感じにアニメーションを行うことが出来ます。
今日は、requestAnimationFrameという機能についてブログを書きたいと思います。
以下のように使うことが出来ます。
「それ困るんじゃない?」と感じるかと思いますが、ブラウザの実行速度を意識したfpsの設定をわざわざしなくて良いという点で便利です。 例えば実行速度が速い環境ではfpsを60に、遅い場合にはfpsを12にしたいといった実装をsetTimeoutでは行う必要がありますが、requestAnimationFrameでは行う必要がありません。ブラウザ任せです。
またrequestAnimationFrameを使うと、アニメーションが滑らかになります。setTimeoutでアニメーションする際には、プログラムが指定したFPSでアニメーションしようとしますが、そのFPSがブラウザのFPSと合っていないことも多く、アニメーションが飛んだり角付いたりする原因となっています。
requestAnimationFrameでは、アニメーションのFPSとブラウザのFPSが一致するので、滑らかなアニメーションになります。
http://caniuse.com/#search=requestAnimation
Androidは全滅、IEは10から、iOS/Chrome/Firefoxはいい感じに使えるって所でしょうか。 サポート状況がまばらですので、setTimeoutとの使い分けが必要です。以下ではsetTimeoutとの使い分ける実装方法を記載しました。
こんな感じで、requestAnimationFrameとsetTimeoutを使い分けることが出来ます。
- window.requestAnimationFrame - Web API リファレンス | MDN
- W3C Timing control for script-based animations
- Timing control for script-based animations ("requestAnimationFrame") (Windows)
今後も面白い技術がありましたら、このブログで紹介出来ればと思います。
最後までご覧頂きましてありがとうございました。
JavaScriptを用いてアニメーションを行う際に、setTimeoutやsetIntervalを使ってアニメーションループを実装することが多いと思いますが、 最近使えるようになってきたrequestAnimationFrameを使うと、よりいい感じにアニメーションを行うことが出来ます。
今日は、requestAnimationFrameという機能についてブログを書きたいと思います。
requestAnimationFrameとは
requestAnimationFrameとは、setTimeoutと似たような機能で、ブラウザの次の描画の際に実行したい関数を指定することで、 ブラウザが次回描画時に呼び出してくれる機能です。以下のように使うことが出来ます。
winodow.requestAnimationFrame(function() { // アニメーションで実行したい処理 }); // setTimeoutの場合はこんな感じで使うかと思います。 setTimeout(function() { // アニメーションで実行したい処理 }, 50);上記2つのコードで大きく違うところは、次回呼び出しをいつ行うかを指定できるか否かです。 setTimeoutでは第2引数にミリ秒単位で次回呼び出し時間を指定できますが、requestAnimationFrameでは指定できず、次回呼び出しはブラウザに依存します。
「それ困るんじゃない?」と感じるかと思いますが、ブラウザの実行速度を意識したfpsの設定をわざわざしなくて良いという点で便利です。 例えば実行速度が速い環境ではfpsを60に、遅い場合にはfpsを12にしたいといった実装をsetTimeoutでは行う必要がありますが、requestAnimationFrameでは行う必要がありません。ブラウザ任せです。
またrequestAnimationFrameを使うと、アニメーションが滑らかになります。setTimeoutでアニメーションする際には、プログラムが指定したFPSでアニメーションしようとしますが、そのFPSがブラウザのFPSと合っていないことも多く、アニメーションが飛んだり角付いたりする原因となっています。
requestAnimationFrameでは、アニメーションのFPSとブラウザのFPSが一致するので、滑らかなアニメーションになります。
requestAnimationFrameは非アクティブウインドウでは手を抜く
requestAnimationFrameは、対象ウインドウが非活性時(違うタブを開いているとか)の場合には、処理が間引かれたり止まったりして、PCのCPUに負荷を掛けないようになってい(るようです)ます。setTimeoutだと非活性時にも動いちゃってPCに負荷を掛けるので、この動きは良いですね。requestAnimationFrameの実装状況
Webで便利なものは、各ブラウザの実装状況が気になります。「Can i use」サイトによると、以下のような実装状況のようです。http://caniuse.com/#search=requestAnimation
Androidは全滅、IEは10から、iOS/Chrome/Firefoxはいい感じに使えるって所でしょうか。 サポート状況がまばらですので、setTimeoutとの使い分けが必要です。以下ではsetTimeoutとの使い分ける実装方法を記載しました。
requestAnimationFrameを使える場合には、setTimeoutよりも優先して使う
requestAnimationFrameとsetTimeoutは、メソッドシグニチャや使い方が近しいので、使い分けが簡単です。 以下のように実装することで、使い分けをすることが出来ます。// アニメーションループに使うメソッドを決める var animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.setTimeout; // アニメーションを行うメソッドを定義する。 var animation = function() { // 描画する draw(); // 次描画の計算を行う calc(); // 次呼び出しを予約する // 第2引数は、setTimeoutの場合のみ使われる animationFrame(animation, 1000 / 24); }; // アニメーションを行う animation();requestAnimationFrameはベンダープレフィックス付きの場合もあるので、色々と試しながらanimationFrame変数に代入します。 その後は、setTimeoutを使うのと同じように、アニメーションを実装します。
こんな感じで、requestAnimationFrameとsetTimeoutを使い分けることが出来ます。
参考資料
requestAnimationFrameについては、以下のサイトの情報が役立ちました。- window.requestAnimationFrame - Web API リファレンス | MDN
- W3C Timing control for script-based animations
- Timing control for script-based animations ("requestAnimationFrame") (Windows)
最後に
Web世界は便利なものがドンドン出てきますね。新しいことを学ぶのは楽しい限りです。今後も面白い技術がありましたら、このブログで紹介出来ればと思います。
最後までご覧頂きましてありがとうございました。