Scroll Smoothing UI(Inertiaの基礎)

Scroll Smoothing UIのアイキャッチ画像

1.Scroll Smoothing UIとは?

スクロールの値(scrollY)をそのまま使うと、動きは正確ですが少し硬く感じます。

そこで使うのが Scroll Smoothing です。

スクロール位置をそのまま表示に使うのではなく、少し遅れて追従させることで、なめらかな動きを作ります。

このような補間処理は、JavaScriptのアニメーションの基本となる考え方です。

まだrequestAnimationFrameに慣れていない場合は、先にこちらを読むのがおすすめです。
requestAnimationFrameの使い方

2.なぜ気持ちよく感じるのか?

人間の感覚は「完全に一致した動き」よりも、
わずかに遅れて追従する動きに対して自然さを感じます。

これはUIにおける「慣性」のようなものです。

ただしここではまだ物理計算は使いません。
あくまで「補間」です。

3.基本の考え方

2つの値を用意します。

  • target(実際のスクロール位置)
  • current(表示に使う値)

この2つを少しずつ近づけます。

4.lerpで追従させる

lerp(線形補間)を使うと、簡単に実装できます。

今回の実装では、lerp(線形補間)を使って値を滑らかに変化させています。

lerpの仕組みについて詳しく知りたい場合は、こちらで解説しています。
lerp(Interpolation)とは?

5.実装

<div class="wrapper">
  <div class="content">
    <section>Section 1</section>
    <section>Section 2</section>
    <section>Section 3</section>
    <section>Section 4</section>
  </div>
</div>
body {
  margin: 0;
  overflow-x: hidden;
  font-family: sans-serif;
}

.wrapper {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

.content {
  will-change: transform;
}

section {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
}
let current = 0
let target = 0

window.addEventListener("scroll", () => {
  target = window.scrollY
})

function update() {
  current += (target - current) * 0.1

  document.querySelector(".content").style.transform =
    `translateY(${-current}px)`

  requestAnimationFrame(update)
}

update()

このように、入力(scroll)と表示(transform)を分離する設計は、UIアニメーションでは非常に重要です。

状態管理の考え方については、こちらの記事も参考になります。
JavaScript 状態管理の基本

6.ポイント解説

なぜtransformを使うのか

topmarginではなく、transformを使うことでパフォーマンスが安定します。

transformを使うことで、レイアウト計算を発生させずに滑らかに動かすことができます。

パフォーマンスと描画の仕組みについては、こちらで詳しく解説しています。
フレームレートとパフォーマンス

係数(0.1)の意味

current += (target - current) * 0.1
  • 小さい → ゆっくり(ぬるぬる)
  • 大きい → 速い(カクつきやすい)

なぜscrollYを直接使わないのか

そのまま使うと「入力と表示が完全一致」します。

👉 これが逆に“硬さ”の原因です。

7.実験:Scroll Smoothing Playground

観察してみてください:

  • スクロールを速くすると遅延が生まれる
  • ゆっくり動かすと自然に追従する
  • 係数を変えると挙動が変わる

8.よくある失敗

❌ bodyにoverflow:hiddenをつけただけで終わる

→ スクロール量の高さが足りないと動きません

❌ 高さを計算していない

必要なら以下を追加:

document.body.style.height =
  document.querySelector(".content").offsetHeight + "px"

9.応用

この考え方は様々なUIに応用できます。

  • パララックス
  • Scroll Story UI
  • Sticky UIとの組み合わせ

10.Inertia Scrollとの違い

Scroll Smoothingは「補間」です。

一方で Inertia Scroll(Momentum UI) は、
速度や減衰を使った「物理モデル」です。

👉 より自然なスクロールを作りたい場合はこちら
Inertia Scroll / Momentum UI

11.まとめ

Scroll Smoothingの本質はこれです。

👉 スクロールは入力、表示は補間する

この考え方を使うことで、
UIの質は一段上がります。

スクロールに関する他のUIパターンもまとめています。


Scroll Animationシリーズ

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA