[JavaScript] Lozad.js を使ってスクロールにあわせたふわっとアニメーションを実装する
画像などの遅延読み込み(Lazy loading)のライブラリとして紹介されることの多い Lozad.js ですが、「要素が画面内に入ってきたらふわっと表示させる」というようなアニメーションの実装にもぴったりです。
他のスクロール監視系ライブラリの多くは scroll
イベントと getBoundingClientRect()
の組み合わせで要素の位置を監視しています。一方、 Lozad.js
は Intersection 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 も併せて使いましょう。