滑らかな慣性スクロールを付与![Lenis]で良質なスクロール体験をWebサイトに加える方法

滑らかな慣性スクロールを付与![Lenis]で良質なスクロール体験をWebサイトに加える方法
Webサイトを閲覧する時、ユーザーは、縦にスクロールを行い、情報を閲覧しますよね。

物が動きだして、そして止まる時。自然界では「慣性」がはたらいて、止まる前にゆるやかに減速して停止しますよね。

人間もそれを見慣れているので、Webサイトを見ている際も「ぴたっ」と動きが止まってしまうより、
スクロールを止めた時に「慣性」がはたらいていたほうが、「心地よく感じる」わけです。

今回は、そんな「慣性スクロール」を手軽に付与できるJSライブラリ「Lenisについて、記事を書いていきたいと思います。
(記事の後半では、CSSアニメーションの新概念「ScrollTimeline」「ViewTimeline」を組み合わせたデモなどもあります)

JSライブラリ[Lenis]の使い方。「慣性」をスクロールでも再現。物が動いて止まる時、緩やかに減速して停止する

早速ですが、慣性スクロールをページに付与してくれるJSライブラリ、
「Lenis」の使い方です。

まずは、Webサイトにライブラリを読み込みます。
今回は試しに使ってみたいので、CDNから読み込むことにします。

<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@1.0.19/bundled/lenis.min.js"></script>

↑CDNのほか、npmでのインストールも可能です。

上記、CDN読み込みをbodyの閉じタグ直前付近で行った後に続いて、
新しいscriptタグの中に次のコードを記述します。

const l = new Lenis();

function inertia(t) {
  l.raf(t); // ← ライブラリ組み込みメソッド raf() を実行
  requestAnimationFrame(inertia);
}

requestAnimationFrame(inertia);

上記コードの説明など

JS側の説明です。
まず、1行目ですが new Lenis(); として、Lenisオブジェクトを生成。
変数lに格納しています。(変数名はなんでも良いです。公式サンプル同様にlenis、とするのが分かりやすいかもしれません)

続いて3行目ですが、これは8行目にある requestAnimationFrame() に実行してもらう挙動を定義した関数です。
4行目l.raf(t); は、Lenis組み込みメソッドの raf() を実行している記述です。Lenis を使うために、かならず必要な記述になります。
(詳しくは Lenis公式のこのリンク先 に仕様が書かれています。「Must be called every frame for internal usage.(内部使用のためにフレームごとに呼び出す必要あり)」と記載されていて、必ず実行が必要なことがわかります。)

5行目は、JavaScritptの requestAnimationFrame() メソッドを使い、この関数自身を再度実行させています。なぜこうしているかは、後述します。

そして8行目。
requestAnimationFrame(inertia); として、3〜6行目で定義した関数 inertia() を初回実行させています。

上記のポイント

ポイントとなるのは、requestAnimationFrame(inertia); の部分になります。

requestAnimationFrame() は、JavaScript自体がもつメソッドです。
ブラウザーに動き(アニメーション)を行いたいことを知らせる
指定した関数を呼び出して、次の再描画が起きる前に動き(アニメーション)を更新させる
という性質を持っています。

つまり、上記の8行目の requestAnimationFrame(inertia); で、3〜6行目で定義した挙動を実行させているわけです。

ここで注目してほしいのは、5行目で「もう一度 requestAnimationFrame(inertia); を実行させている点」です。

8行目で1回、inertia() 関数を実行して、
→ inertia() 関数自身の中でも、もう一度 inertia() が実行されています。

requestAnimationFrame() は、
その次のフレーム(ブラウザの描画タイミング)で、渡された関数を再実行」してくれる性質があるため、
このように初回実行、関数の中でも再実行、のように記述する事で
ずっと、Lenis組み込みのメソッドである raf() が動き続けるため、
結果として慣性スクロールがページ上で実現されることになる、と言うわけです。

これ一見、「無限ループしちゃってやばいんじゃないの?」と思うかもしれません。
私も最初、そう思ったんですが、実際に上記の記述で慣性スクロールを動かしてみると、
まったく重くもなく、ブラウザが止まってしまうこともなく
むしろ自然に動くという結果でした。

なぜ問題なく動くかと言うと、
これは「 requestAnimationFrame() の仕様のおかげ」でした。

requestAnimationFrame() は、「ディスプレイのリフレッシュレートに合わせて実行される」仕様になっているため、過度なCPU負担がかからず、問題なく動作する模様です。


こちらの requestAnimationFrame()
JavaScriptからアニメーション制御を行う場合、とても有用なメソッドだと言う事がわかりました。

実際に動かせるサンプル

次のリンクに、
上のセクションのサンプルコードを動かせるデモページを用意しました。

ページをスクロールすると、自然な慣性スクロールが発生している事がわかるかと思います。
※なおスマートフォンのブラウザはデフォルトで慣性スクロールがついているため、あまり変化ないと思います。PCから見た際に、違いがわかりやすくなっています。

慣性スクロールがLenisによって付与されたページのサンプル

Scroll Timeline, View Timelineも自然な動きに!!

ここ最近、当サイトではCSSの新しい概念である
Scroll Timeline, View Timeline に関する記事を、次のように5記事ほど、書いています。

【CSSだけ】メインビジュアルがヘッダーに変化!スクロールに応じて斬新な視覚表現をつくる方法[Scroll Timeline]
(↑これは上のセクションにあるデモの内容を解説している記事です)
【CSSのみ】画像がスクロールに応じて出現!新概念をつかって印象的な視覚効果を作る方法[Scroll Timeline, View Timeline]
【CSSだけ】続編: スクロールに連動して要素が動く!新概念をつかった視差エフェクトを作る方法[ScrollTimeline, ViewTimeline]
【驚き】CSSだけでスライダーが!? 新概念「Scroll Timeline」を「View Timeline」と組み合わせて、スライダー風UIを作成する方法
CSSアニメーションの新概念!Scroll Timelineの概念を使ってページのプログレスバーを作る方法[animation-timeline]

↑これらの記事の中で出てきたデモページも、今回の「慣性スクロール」をプラスしてあげる事で、PCブラウザ上でもずいぶん
「自然な動き」にする事ができました。

慣性スクロールを付与したバージョンのデモを作成しましたので、次の各リンクより、実際に動かして確認ができます!
※比較対象として、それぞれ
[慣性スクロール版]
[通常版]
を続けてリンクとして置いてあります。見比べてみると、慣性スクロールによる効果がよくわかるかと思います。

【ScrollTimelineの例:メインビジュアルがスクロールに応じてヘッダーに変化】
[慣性スクロール版](←これは上のセクションのデモと同じもの)
[通常版]

【ScrollTimelineの例:CSSだけで作れる!パララックス効果のサンプル】
[慣性スクロール版]
[通常版]

【ScrollTimelineの例:CSSだけで出来ているスライダー】
[慣性スクロール版]
[通常版]

Lenisを使用する際に気をつけること

さてこちらのJSライブラリ「Lenis」、
Webサイトに慣性スクロールを手軽に付与できる優れたライブラリですが、使用する際にすこし留意点があります。

それは、「cssの scroll-behavior を使用しない」ということです。

たまに、html要素自体に scroll-behavior: smooth; をかけているWebサイトをみかけます。

しかしその状態で Lenis を動かそうとすると、挙動が不安定になります(期待通りに動作しなくなります)。

Lenisを使用するページでは、
「scroll-behavior を使用しない」または
「scroll-behavior: initial;」「scroll-behavior: auto;」
のように、使用しない事を明示する

と言う事を覚えておくと、いつかどこかで役に立つかもしれません。

requestAnimationFrame() のMDNでの解説ページ

さて、今回は「慣性スクロール」をLenis、というライブラリを使って付与する記事を書いたわけですが
動かす際に重要となる、requestAnimationFrame() について、
ご存知、MDNに詳しい解説ページがあります。

Window.requestAnimationFrame() – Web API | MDN

↑上のセクションで書いた、requestAnimationFrame() の仕様 に関する説明がひととおり細かく掲載されています。
一読すると、理解が深まるかと思います。

この記事のまとめ

今回は「慣性スクロール」をLenis、というライブラリを使って付与する記事を書いてみました。

いかがでしたでしょうか。
冒頭に「物が動きだして、そして止まる時。自然界では「慣性」がはたらいて、止まる前にゆるやかに減速して停止する」

という一文を書きましたが、

我々は、普段からそれを見慣れているので、「自然だ」「心地よい」と感じるわけですね。
これは、デザインにおいて「黄金比」「白銀比」などの比率が「なぜ心地よいと感じるか?」
という話とよく似ています。
この話をすると、「フィボナッチ数列」とか、デザイン理論の難し〜い話になってしまうので
このくらいに留めておきますが、

ものすごくざっくり言うと
人間というのは、自然界の法則に存在する事象を、おのずと心地よいと感じる生き物だということです。

この記事が皆さんのより良いWeb制作体験につながれば、嬉しく思います。

※この記事は内容の品質向上を目的に、随時更新を行う場合があります。


Scroll Timeline, View Timelineについての参考文献等:
Scroll-driven-animations(https://scroll-driven-animations.style/) – Copyright (c) Bramus (https://github.com/bramus), Chrome Developer Relations Engineer at Google
┗ License – https://www.apache.org/licenses/LICENSE-2.0.txt (Apache License Version 2.0)
scroll-timeline.js – Copyright (c) Robert Flack (https://github.com/flackr)
┗ License – https://www.apache.org/licenses/LICENSE-2.0.txt (Apache License Version 2.0)

lenisについて:
lenis – Copyright (c) darkroom.engineering – https://github.com/darkroomengineering/lenis
License – https://github.com/darkroomengineering/lenis?tab=MIT-1-ov-file#readme (The MIT License (MIT), Copyright (c) 2024 darkroom.engineering )

この記事をシェアする: