IntersectionObserverでスクロールアニメーション

どうも、くまだです。

IntersectionObserverを使って簡単なアニメーション実装。

IntersectionObserverでスクロールアニメーション

コードは以下になります。

    <div class="l-container">
      <section class="p-section">
        <div class="p-section__contents">
          <div class="p-section__block js-fade">
            <div class="p-section__img">
            </div>
            <div class="p-section__textBox">
              <h2>タイトルタイトル</h2>
              <p>テキストテキスト</p>
            </div>
          </div>
          <div class="p-section__block js-fade">
            <div class="p-section__img">
            </div>
            <div class="p-section__textBox">
              <h2>タイトルタイトル</h2>
              <p>テキストテキスト</p>
            </div>
          </div>
        </div>
      </section>
      <section class="p-section">
        <div class="p-section__contents">
          <div class="p-section__block js-fade">
            <div class="p-section__img">
            </div>
            <div class="p-section__textBox">
              <h2>タイトルタイトル</h2>
              <p>テキストテキスト</p>
            </div>
          </div>
        </div>
      </section>
      <section class="p-section">
        <div class="p-section__contents">
          <div class="p-section__block js-fade">
            <div class="p-section__img">
            </div>
            <div class="p-section__textBox">
              <h2>タイトルタイトル</h2>
              <p>テキストテキスト</p>
            </div>
          </div>
          <div class="p-section__block js-fade">
            <div class="p-section__img">
            </div>
            <div class="p-section__textBox">
              <h2>タイトルタイトル</h2>
              <p>テキストテキスト</p>
            </div>
          </div>
        </div>
      </section>
    </div>

.p-section {
  padding: 100px 80px;
  background-color: lightcyan;
}

.p-section:nth-child(odd) {
  background-color: lightblue;
}

.p-section__contents {
  text-align: center;
}

.p-section__block {
  display: flex;
  justify-content: center;
}

.p-section__img {
  margin-right: 20px;
  width: 400px;
  height: 300px;
  background-color: red;
}


.p-section__block {
  transition: transform .8s, opacity .8s;
  transform: translateY(50px);
  opacity: 0;
}

.p-section__block + .p-section__block {
  margin-top: 20px;
}



.p-section__block.is-active {
  transform: translateY(0);
  opacity: 1;
}
document.addEventListener('DOMContentLoaded', () => {

  const fadeTargets = document.querySelectorAll(".js-fade");

  function targets(entries) {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        entry.target.classList.add("is-active");
      }
    });
  }

  const options  = {
    root: null,
    rootMargin: "-10% 0px",
    threshold: 0
  };


  const fadeObserve = new IntersectionObserver(targets, options);

  fadeTargets.forEach((target) => {
    fadeObserve.observe(target);
  });

});

See the Pen IntersectionObserverでスクロールアニメーション by kuma0605 (@kuma0605) on CodePen.

IntersectionObserverは指定した要素と基準要素が交差するのを非同期で監視してくれる機能です。

スクロールして「見ている画面」と「アニメーションする要素」が交差したとき(要するに画面内に入ったとき)に、関数を実行します。

スクロールアニメーションというと、まずGSAPが思い浮かびますが、簡単なスクロールアニメーションであればIntersectionObserverでも実装できます。IntersectionObserverは非同期で実行されるので、GSAPよりもパフォーマンス的にもいいとされています。

また、GSAPと違ってCDNなど別途読み込む必要もなく使うことができます。

指定できるオプション

〇 root

どの要素を基準にするか。デフォルトがnullで、画面の大きさが基準になります。

〇 rootMargin

設定したrootからの交差位置を設定。

例えば、rootMargin: “-10% 0px”,とすれば、rootの基準から上下位置が10%に広がった位置で交差判定となります。

〇 threshold

0~1の値を設定。

ターゲットの要素がどれくらい基準の要素と交差したかを設定できます。

0で交差した瞬間に発火、1で要素全体が交差し終わったときに発火されます。

ちょっとしたスクロールアニメーション程度であれば、IntersectionObserverでも十分で、その他に複雑なアニメーションが必要ならGSAP、という感じの使い分けでいいかもしれない。

ここまで読んでくださりありがとうございました。

この記事を書いた人