
【JavaScript】requestAnimationFrame() を使った、ループスクロールアニメーション
目次
requestAnimationFrame()とは?
スムーズなアニメーションのためのJavaScript関数
Webでアニメーションを作っていると、こんな疑問にぶつかることがあります。
「setInterval() や setTimeout() で動かしてるけど、なんかカクつく…?」
「ブラウザの動きに合わせて、もっとスムーズに動かせないの?」
そんなときに登場するのが、JavaScriptの requestAnimationFrame() です。
そもそも何をする関数?
requestAnimationFrame() は、ブラウザに「次の再描画のタイミングでこの関数を実行してね」とお願いする関数です。
- function animate() {
- // ここでアニメーションの処理を書く
- box.style.left = box.offsetLeft + 1 + 'px';
- // 次のフレームでもまたこの関数を呼び出す
- requestAnimationFrame(animate);
- }
- requestAnimationFrame(animate);
上のコードでは、animate() が呼ばれるたびに box がちょっとずつ右に動きます。
requestAnimationFrame() を使うことで、約60fps(1秒に60回)のスムーズなアニメーションを実現できます。
setInterval() より良いの?
一見、setInterval() を使っても同じようにアニメーションできそうですが、requestAnimationFrame() には以下のような大きなメリットがあります。
1.ブラウザに最適なタイミングで動く
requestAnimationFrame() は、ブラウザの画面更新に合わせて関数を呼び出すので、ムダな処理を省いてなめらかになります。
2.非表示のタブでは止まる
ユーザーが他のタブを見ている間は、requestAnimationFrame() の処理が止まります。これによって、CPUやバッテリーの無駄な消費を防ぐことができます。
3.自動で60fpsに調整される
60fpsを基準に最適化されていて、タイミングが均等になるため、チラつきやカクつきが起きにくくなります。
アニメーションを作るならまず使おう!
最近では、requestAnimationFrame() はWebアニメーションの基本とも言える関数です。
Canvas、SVG、DOMアニメーション…どんな種類でもこの関数を使うことで、滑らかで効率的な動きを実現できます。
一度だけ呼び出したいときは?
- requestAnimationFrame(() => {
- console.log("1フレーム分後に実行されました");
- });
以上のように一回だけの処理でも使えます。アニメーションじゃなくても、次の描画タイミングに処理を合わせたいときにも便利です。
要素がループして移動するアニメーション
See the Pen
Untitled by ryotom (@ryotam-smoke)
on CodePen.
position が window.innerWidth(画面の幅)を超えたら、-boxWidth(つまり左端の外)にリセットします。
これにより、要素は画面をスムーズに通過し、また左から出現してループします。
タイミングや速度を変えたい場合は speed を調整してください。