目的と課題
スクロール値の増減に併せて、特定の要素のスタイルの値も増減するアニメーションをスムーズに動作させたいです。
しかし、スクロール時にガタつきが発生してしまうのでその原因と対策を模索しています。
お手数をかけますがご助言いただけますと幸いです。
具体的な問題
スクロールの増減によって画像の要素の「padding-top」を同様に増減させ、画像がその場に停滞して見えるような処理を実装しているのですが、下記URLの動画のように、主にスクロールの開始直前くらいのタイミングで要素がガタガタと揺れてしまいます。
https://vimeo.com/855227603/1b0406ea35?share=copy
スクロールイベントの多発によるブラウザへの負荷でこのような現象が起きているのではないかと予想してはいるのですが、そもそもその原因で合っているのか、合っていたとしてもどのように改善すればいいかがわからない状態です。
現在のコード(簡易版)
動画のサイトのコードをより簡略化したものが下記のコードです。HTMLやCSSが異なりますが、JSのコード自体は動画のものと全く同じです。
こちらの方が内容が軽いせいか、動画ほど頻繁にガタつきが発生しませんが、こちらのコードでもスクロール開始のタイミングでガタつきが発生してしまいます。
html
1<div id="box" class="box"> 2 <div class="box__wrapper"></div> 3</div> 4<div class="subBox"></div>
css
1.box { 2 width: 100%; 3 background: #555; 4} 5.box__wrapper { 6 width: 100%; 7 height: 600px; 8 background: #000; 9} 10.subBox { 11 width: 100%; 12 height: 3000px; 13 background: #eee; 14}
JavaScript
1const box = document.getElementById("box"); 2 3let ScrollCount = 0; 4function scrollCount() { 5 let ScrollCount_before = ScrollCount; 6 ScrollCount = window.scrollY; 7 let ScrollCount_diff = ScrollCount - ScrollCount_before; 8 9 requestAnimationFrame(function () { 10 if (ScrollCount_diff > 0) { 11 for (let i = 1; ScrollCount_diff >= i; i++) { 12 let countUp = ScrollCount_before + i; 13 console.log(countUp); 14 box.style.paddingTop = countUp + "px"; 15 } 16 } else { 17 for (let i = 1; ScrollCount_diff * -1 >= i; i++) { 18 let countDown = ScrollCount_before - i; 19 console.log(countDown); 20 box.style.paddingTop = countDown + "px"; 21 } 22 } 23 }); 24} 25window.addEventListener("scroll", scrollCount); 26
補足
JSのスクロールカウント処理についてですが、スクロールのスピードに関わらず1pxずつの増減を実現するために上記のようなコードにしています。
CSS側のスタイルに関しては「paddingではなくfixedにした方が良い」など、アプローチの方法はいくつかあるかと思いますが、今回についてはpaddingの値の増減で制御するという前提は変えない(変えられない)ということでご検討いただきたいです。
