🐶

Locomotive Scroll がv5になっていい感じになったまとめ!!

に公開

主な変更点

スムーススクロール(滑らかなスクロール)エンジンの変更

Lenisをベースに構築されています。

パフォーマンスが改善されたよ!

  • ファイルサイズが軽量化
  • 2種類Intersection Observerを使い分けて処理を軽くした実装が可能になった。

他の箇所で使用するCSSに影響がなくなった

v4はページ全体をラップしてtransformで動かしていたため、position: fixedが効かなくなるなどレイアウトが崩れる問題があった。v5ではposition: fixedやposition: stickyがそのまま使えるようになった。

2種類のIntersection Observerとは?

v4ではすべての要素を毎フレーム(60fps = 1秒に60回)で監視していました。これでは単純な処理でも重くなってしまいます
v5では単純な検出 と 連続アニメーション の2種類を使い分けることによって処理の最適化が図れるようになりました。

単純な検出の場合の例(処理が軽い)
クラスを付与する時とかに有効

<div data-scroll data-scroll-class="is-visible">タイトル</div>

連続アニメーションの場合の例(処理が重いけど必要)
パララックスなどフレームごとで処理が必要な時に有効

<div data-scroll data-scroll-speed="2">パララックス画像</div>

使い方

至ってシンプル
ライブラリのCSSとJSをインポートして
new LocomotiveScroll();を初期化するだけ

 <main style="height: 150vh;">
    <div>
        <h1>Hello 👋</h1>
    </div>
    <div>
        <h2 data-scroll data-scroll-speed="0.5">What's up?</h2>
        <p data-scroll data-scroll-speed="0.8">😬</p>
    </div>
</main>
@import 'locomotive-scroll/dist/locomotive-scroll.css';
import LocomotiveScroll from 'locomotive-scroll';
const locomotiveScroll = new LocomotiveScroll();

Q.LenisベースならLenis使った方が良くない?何が違うの?

Lenisはスムーススクロールだけを提供するライブラリです。
Locomotive Scroll v5は「Lenis + 便利機能」という位置づけかなと思いました!
便利機能(属性)としては以下のような例が挙げられます!

機能 Lenis Locomotive v5
スムーススクロール ⚪︎ ⚪︎
ビューポート検出 × data-scroll
クラス追加(デフォルト: is-inview) × data-scroll-class
パララックス × data-scroll-speed
要素ごとの進捗値 × data-scroll-css-progress
カスタムイベント × data-scroll-call

以下はLocomotive Scrollで使える便利な属性の例を付与した例です。
発火タイミングなど自由に調整して挙動を確かめてもらっても良いかもです!

      <div class="wrapper">
        <div
          class="box"
          data-scroll
          data-scroll-repeat
          data-scroll-offset="30%,30%"
          data-scroll-position="end,start"
          data-scroll-call="scrollEvent"
        >
          <div class="box__info">
            <div class="box__status">false</div>
          </div>
        </div>
      </div>
      <div class="trigger-lines">
        <!-- enter: 要素の下端がここを通過するとIN VIEW -->
        <div class="line line--enter" data-label="ENTER (画面下から30%)">
          <span class="line__desc">要素の下端がここを通過で発火</span>
        </div>
        <!-- leave: 要素の上端がここを通過するとOUT -->
        <div class="line line--leave" data-label="LEAVE (画面上から30%)">
          <span class="line__desc">要素の上端がここを通過で終了</span>
        </div>
      </div>
/* Import styles */
import "./styles.css";

/* Import locomotive-scroll */
import "locomotive-scroll/bundled/locomotive-scroll.css";
import LocomotiveScroll from "locomotive-scroll";

/* Locomotive scroll instance */
const locomotiveScroll = new LocomotiveScroll();

/* Custom event */
window.addEventListener("scrollEvent", (e) => {
  const { target, way } = e.detail;

  if (way === "enter") {
    target.style.backgroundColor = "pink";
  } else {
    target.style.backgroundColor = "";
  }
});

追記:data-scroll-call のカスタムイベントの解説

プロパティ 値 意味
target DOM要素 data-scroll-callが付いてる要素
way "enter" 画面に入った
"leave" 画面から出た

流れ

スクロールして要素が画面に入る
        ↓
Locomotive Scrollが検知
        ↓
window に "scrollEvent" イベントを発火
        ↓
window.addEventListener("scrollEvent", ...) が受け取る
        ↓
e.detail の中身を使って処理

e.detailの中を見てみると以下のような情報があります。
発火エリアに入った時

発火エリアを過ぎた時

この情報を元に必要な処理を行います。

window.addEventListener('scrollEvent', (e) => {
  console.log(e.detail);
  const { target, way } = e.detail;
 if (way === "enter") {
   //wayが"enter"(要素に入った時)
    target.style.backgroundColor = "pink";
  } else {
    target.style.backgroundColor = "";
  }
});

まとめ

v4までのラッパーの中をtransformでいじるといったの魔改造感がなくなってかなりスッキリした印象です。「スムーススクロール + ちょっとしたパララックス」くらいの要件なら、v5でサクッと実装するのが良さそうですしGSAPでゴリゴリ制御したい場合はLenis単体の方が小回りが利くかもしれません。公式ドキュメントも刷新されているので、気になった方はぜひ触ってみてください。
https://scroll.locomotive.ca/docs

Discussion