Scroll Listener vs Intersection Observer
スクロール時にアニメーションするには、要素が今どこにあるか常に把握する必要がある。
Event listenerでスクロールアクションを監視する方法が多いが、Intersection Observerというパフォーマンスの優れたAPIがあるので、それを使ってスクロール時のアニメーションを実装する。
How to use
基本的な使い方としては、observerを作り要素を監視させるだけ。
const observer = new IntersectionObserver(callback, options);
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entry.isIntersecting // return boolean
})
},
{
// option
}
)
observer.observe(targetElement)
callbackで IntersectionObserverEntry というオブジェクトを受け取り、その中のisIntersectingというプロパティを使うことで、要素がスクリーンの中に入ったかどうか検知することができる。
Options
observerを作成する際にオプションを設定することができ、thresholdの値をうまく設定することで、要素がどの程度スクリーンに入ったところで検知するかを調整することができる。
thresholdの値は0から1の間で設定でき、1なら要素とスクリーンの交差(Intersection)が100%になった時にisIntersectingがtrueになり、0なら0%、つまりスクリーンと縁と要素の縁が触れたところでtrueになる。
図にするとこんな感じ。
さらにthresholdを配列で設定することにより、細かく要素の位置を検知することができる。
試しにthresholdを[0, 0.01, 0.02 … 0.99, 1]という100段階に設定して、divの背景色を変えてみる。
entry.intersectionRatioを使えば現在要素がどれほどスクリーンに交差しているか取得できる。
const getThresholdArray = () => {
const threshold = []
for (let i=0; i<=1; i+=0.01) threshold.push(i)
return threshold
}
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entry.target.style.backgroundColor = `rgba(22, 22, 22, ${entry.intersectionRatio})`
})
},
{
threshold: getThresholdArray()
}
)
observer.observe(targetElement)
スクリーンと要素のIntersectionの具合に合わせて、divの背景色が変わるのを確認できる。
あとは任意のタイミングで任意のアニメーションを付けていけば、スクロールに合わせて自由にアニメーションを実装することができる。