Web production note

 【更新日 :

【シンプル版改修】【CSS , JavaScript】Intersection Observerでスクロールアニメーションを実装する

Category:
css / js

以下で実装したIntersection Observerでスクロールアニメーションさせる機能を見直し、より軽量に改修したサンプルです。

オプション設定を省き、ループ無しで一回のみ発火するシンプルな挙動です。

codepen

See the Pen Intersection Observer Scroll Animation 【simple】 by web_corder (@web_walking_nak) on CodePen.

HTML

複数アニメーションする場合

  • 親要素に .js-anime を追加。
  • アニメーションさせたい内包要素に .js-anime__item を追加。
<div class="js-anime">
  <p class="js-anime__item">エリア内複数アニメーション要素1</p>
  <p class="js-anime__item">エリア内複数アニメーション要素2</p>
</div>

単一アニメーションの場合

  • 要素に .js-anime と .js-anime__item を追加。
<p class="js-anime js-anime__item">単一アニメーション要素</p>

CSS

.js-anime__item に .is-anime が追加されると発火します。
サイトに合わせて適宜調整をしてください。

.js-anime__item {
  opacity: 0;
  animation-fill-mode: both;
  animation-duration: 1.2s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.js-anime__item.is-anime {
  animation-name: fadeIn;
}
.js-anime__item.is-anime.is-anime-fadeInUp {
  animation-name: fadeInUp;
}
@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translate3d(0,100px,0);
  }
  100% {
    opacity: 1;
    transform: translate3d(0,0,0);
  }
}

JS

rootMarginなど各設定はサイトに合わせて適宜調整してください。

//Intersection Observerスクロールアニメーション
function observerAnime() {
  // ターゲット要素取得
  const targets = document.querySelectorAll('.js-anime');
  // 要素が存在するかチェック
  if (targets.length === 0) {
    return;
  }

  // observer初期設定
  const animeItemClass = 'js-anime__item';
  const animeSetClass = 'is-anime';
  let observer;

  // アニメーション処理
  function addActiveClass(targetClassList) {
    targetClassList.add(animeSetClass);
  }
  function setAnimeClass(entries, observer) {
    entries.forEach((entry) => {
      // ターゲット要素取得
      const target = entry.target;

      // 要素が画面に入ると処理
      if (entry.isIntersecting) {
        // 子要素がある場合は子要素にclassを追加
        const children = target.querySelectorAll('.' + animeItemClass);
        if (children.length !== 0) {
          children.forEach(function(child) {
            addActiveClass(child.classList);
          });
        }

        // 自身に対象classがある場合
        const targetClassList = target.classList;
        if(targetClassList.contains(animeItemClass)) {
          addActiveClass(targetClassList);
        }

        // 要素の監視を解除
        observer.unobserve(target);
      }
    })
  }

  // observer定義関数
  function setObserver() {
    // observer設定
    observer = new IntersectionObserver(setAnimeClass, {
      rootMargin: '-30% 0px -30% 0px',
    });
    targets.forEach(function(target) {
      observer.observe(target);
    });
  }
  setObserver();
}

関数の呼び出し

任意の場所で以下を実行し関数を呼び出してください。

//Intersection Observerスクロールアニメーション関数呼び出し
observerAnime();

関連リンク

参考リンク