やくだつブログ

[JavaScript] Lozad.js を使ってスクロールにあわせたふわっとアニメーションを実装する

画像などの遅延読み込み(Lazy loading)のライブラリとして紹介されることの多い Lozad.js ですが、「要素が画面内に入ってきたらふわっと表示させる」というようなアニメーションの実装にもぴったりです。

他のスクロール監視系ライブラリの多くは scroll イベントと getBoundingClientRect() の組み合わせで要素の位置を監視しています。一方、 Lozad.jsIntersection Observer API で実装されているというのが優位な点です。すごく簡単にいうとブラウザに優しいということですね。

やりかた

// HTML
<p class="lozad">
  Lorem, ipsum dolor sit amet consectetur adipisicing elit. Temporibus nisi saepe atque illo ea odio, doloremque nihil rem molestiae delectus provident exercitationem modi illum odit unde similique officiis, laborum iusto!
</p>
<p class="lozad">
  Lorem, ipsum dolor sit amet consectetur adipisicing elit. Temporibus nisi saepe atque illo ea odio, doloremque nihil rem molestiae delectus provident exercitationem modi illum odit unde similique officiis, laborum iusto!
</p>
<!-- ...以下つづく -->

<!-- lozad.jsの読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js" integrity="sha256-50cmb3K6Zka/WMfXLFzqyo5+P+ue2JdsyEmSEsU58s4=" crossorigin="anonymous"></script>
// CSS
/* 初期値。透明にしてちょっと下の位置に配置 */
p {
  opacity: 0;
  transform: translate3d(0, 1em, 0);
  transition: 
    opacity 0.2s linear,
    transform 0.6s ease-out;
}

p[data-loaded="true"] {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
// JavaScript
document.addEventListener('DOMContentLoaded', function() {
  var observer = lozad('.lozad', {
    rootMargin: '0% 0% -50% 0%' // ← rootMarginの指定が重要!
  })
  observer.observe()
})

ここで重要なのが rootMargin の指定方法です。

画像の遅延読み込みであれば対象の要素が 画面に入ってくる前 に処理をするため、rootMargin: '0% 0% 100px 0%' などとなります。

しかし今回は対象の要素が 画面に入ってきた後 に処理をするためマイナスの値を指定する必要があります。

rootMargin: '0% 0% -50% 0%' だと画面の真ん中に来たタイミング、rootMargin: '0% 0% -33% 0%' だと画面のおよそ2/3に到達したときに処理がされるということです。

そうしましたらば rootMargin で指定した位置に対象の要素が到達したタイミングで data-loaded="true" という属性が付与されますので、これに対して表示後のスタイルを記述すればOKというわけです。簡単!

任意の処理を追加する

loaded オプションで表示の際の処理を追加できます。data-loaded="true" が付与されるのと同じタイミングで呼び出されます。

ここで TweenMax を使用すれば CSS のみではなかなか再現しづらいバウンスアニメーションなども実装することができます。

// HTML
<p class="lozad">
  Lorem, ipsum dolor ...以下略
</p>
<p class="lozad">
  Lorem, ipsum dolor ...以下略
</p>
<!-- ...以下つづく -->

<!-- TweenMaxの読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js" integrity="sha256-lPE3wjN2a7ABWHbGz7+MKBJaykyzqCbU96BJWjio86U=" crossorigin="anonymous"></script>

<!-- lozad.jsの読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js" integrity="sha256-50cmb3K6Zka/WMfXLFzqyo5+P+ue2JdsyEmSEsU58s4=" crossorigin="anonymous"></script>
// CSS
// 初期値だけCSSで指定しておく
p {
  font-size: 2em;
  opacity: 0;
  transform: scale(0);
}
document.addEventListener('DOMContentLoaded', function() {
  var observer = lozad('.lozad', {
    rootMargin: '0% 0% -50%',
    // 表示されるときに TweenMax を使用する
    loaded: function(el) {
      TweenMax.to(el, 1, {
        opacity: 1,
        scale: 1,
        ease: Bounce.easeOut
      })
    }
  })
  observer.observe()
})

注意点

例によって Internet Explorer11 は IntersectionObserver 非対応ですので w3c/IntersectionObserver の Polyfill も併せて使いましょう。

戻る