物体を回転させるアニメーションを作っていたのですが、何か挙動がおかしいことに気が付きました。時間が経つごとに回転の速度が加速していき、そのうち動きがカクカクになってしまいます。おそらく、回転速度が速くなりすぎてカクカクになっているかと思います。
【修正前】アニメーションの速度がどんどん加速してしまう - YouTube
ソースの確認
// 問題のあるソースコード
var scene, camera, renderer, controls;
var sphere;
init();
animate();
function init() {
// 物体をシーンに追加
// 球とトーラスは親子関係にしてあります
}
function animate() {
requestAnimationFrame(animate);
render();
update();
}
// 情報の更新
function update() {
controls.update();
shpereUpdate();
}
// レンダリング
function render() {
renderer.render(scene, camera);
}
function shpereUpdate() {
sphere.rotation.x += 0.01;
setTimeout(shpereUpdate, 100);
}
原因はsetTimeoutにありました。 実はrequestAnimationFrameは無限ループが行われてました。これはsetIntervalをアニメーション向けにしたようなものです。
requestAnimationFrameがあればsetTimeoutは必要ない
requestAnimationFrameは描画が必要ない時は処理を行わないなどの機能があります。例えば、ブラウザで別タブを閲覧中は、無限ループが停止しています。FPSに関しては60fpsを再現しているようです。つまり、requestAnimationFrameを使っていれば、わざわざsetTimeoutは使う必要はありませんでした。
1秒間に約60回もanimateが呼び出されるということは、shereUpdateもその分呼び出され、結果としてsetTimeoutの無限ループの数が増殖してしまいます。つまり、回転させるループ処理は1つではなく、毎秒、約60個も増えていたのです。
ソースの修正
// 修正後
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function shpereUpdate() {
sphere.rotation.x += 0.01;
}
setTimeoutを削除しました。それ以外のことは何もしていません。また、他の関数は省略しています。