Javascript

【Intersection Observer API 】を使ってスクロールアニメーションを実装してみた

今回は【Intersection Observer API 】を使用して、スクロールアニメーションを実装してみたいと思います。

【Intersection Observer API 】ってなに?


Intersection Observer APIIntersectionObserverインターフェースは、ターゲット要素と祖先要素またはトップレベルのドキュメントのビューポートとの交差における変更を非同期で監視する方法を提供します。祖先要素またはビューポートはルートと呼ばれます。

https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserver

ようするに【Intersection Observer API 】を使うと要素やビューポートとの【交差】を監視してくれるということですね。

この仕組みを利用することで、要素が画面内に入ったらアニメーションを実行!みたいな事が実装できるわけです。

JavaScriptのscrollイベントと何が違うの?

通常スクロールアニメーションを実装する時、JavaScriptのscrollイベントを使用して実装することが多いですよね。【in-view.js】といったスクロールで画面内に入ると発火させるプラグインも同様です。

Intersection Observerの場合、要素と要素(ビューポート)が交差したかどうかを監視して、発火させるのでスクロール量とは関係なく実装することができます。パフォーマンス的にもgoodですね!

Intersection Observer API の使い方

Intersection Observerの基本構文を紹介していきます。
流れは以下に。

■交差を監視する要素①、②を指定する。
■要素がどれくらい交差したら発火させるかをオプションで指定する。
■Intersection Observerコンストラクターを呼び出す。
■要素の交差を監視する。
■交差した時に発火させる関数を用意する。

// 交差を監視する要素①を指定する
var observeTargets = document.querySelectorAll('.observeTarget');

// IntersectionObserverのオプション
var options = {
    root: null, //交差を監視する要素②(ベース要素)nullの場合はビューポートが要素②になる 
    rootMargin: "-50% 0px", //要素②に対してのマージン この場合画面50%まできたら発火
    threshold: 0 //要素①に対しての閾値。どのくらいの割合で見えたらという指定 例 1.0で100%
};

// IntersectionObserver起動!
var observer = new IntersectionObserver(observeCallback, options);

// 要素①の監視を開始!
observeTargets.forEach(function (observeTarget) {
    observer.observe(observeTarget);
});

// 交差した時に発火させるコールバック
function observeCallback(entries) {
    entries.forEach(function (entry) {
        if (entry.isIntersecting && !($(entry.target).hasClass('in-view'))) {
            $(entry.target).addClass('in-view');
            $(entry.target).find('.move-item').addClass('move-out');
        }
    })
}

交差を監視する要素①を指定する

交差を監視する要素①を指定します。
今回はスクロールでアニメーションを想定しているので、アニメーションを発火させたい親要素に「class=”observeTarget”」を指定します。

// 交差を監視する要素①を指定する
var observeTargets = document.querySelectorAll('.observeTarget');

交差を監視する要素②(ルート要素)を指定する

交差を監視する要素②(ルート要素)を指定します。
今回は画面内に表示されたら~ というアニメーションなので、ビューポートを指定するため、「null」とします。

// IntersectionObserverのオプション
var options = {
root: null, //交差を監視する要素②(ベース要素)nullの場合はビューポートが要素②になる
};

要素の交差場所をオプションで指定する

要素がどこで交差したら〜 という場所を指定していきます。
感覚としては以下の感じ。

■rootMargin → root側の要素の交差基準を決める
■threshold → 要素①の交差した割合を決める

// IntersectionObserverのオプション
var options = {
    root: null, //交差を監視する要素②(ベース要素)nullの場合はビューポートが要素②になる 
    rootMargin: "-50% 0px", //要素②に対してのマージン この場合画面50%まできたら発火
    threshold: 0 //要素①に対しての閾値。どのくらいの割合で見えたらという指定 例 1.0で100%
};

上の指定の場合、画面の縦幅の半分を要素①が少しでも交差したら発火!

Intersection Observerコンストラクターを呼び出す

Intersection Observerコンストラクターを呼び出します。
以下を指定しないと何も始まりません。

// IntersectionObserver起動!
var observer = new IntersectionObserver(observeCallback, options);

要素①の監視をスタート!

要素①の監視をスタートさせます。

// 要素①の監視を開始!
observeTargets.forEach(function (observeTarget) {
    observer.observe(observeTarget);
});

交差した時のコールバックを用意する。

交差した時に発火させる関数を用意します。

ポイントとしては、entry.isIntersectingの条件分岐です。
isIntersectingは要素①・②が交差したかをtrue or false で返してくれます。これを利用して交差した時に発火させるようにします。

// 交差した時に発火させるコールバック
function observeCallback(entries) {
    entries.forEach(function (entry) {
        if (entry.isIntersecting && !($(entry.target).hasClass('in-view'))) {
            $(entry.target).addClass('in-view');
            $(entry.target).find('.move-item').addClass('move-out');
        }
    })
}

IE11ではそのままでは動作しない

IE11でもIntersection Observerを使用する場合、そのままでは動作しない(対応していない)ため、ポリフィルを使用しましょう。

ポリフィルの詳しいことは以下から。


【Polyfill.io】を使用してJavascriptのブラウザ互換を解決する

今回は以下のポリフィルを読み込ませます。

<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver%2CIntersectionObserverEntry"></script>

Intersection Observer APIを使用したDEMO

最後に、Intersection Observerを使用したスクロールアニメーションのデモを作成してみました。アニメーションはシンプルなフェードインです。

アニメーションは【anime.js】を使用して実装しています。
【anime.js】については以下から。

軽量アニメーションJavascriptライブラリ【anime.js】を使ってみた
【anime.js】を使用したアニメーション①

最後に

使い方に慣れるまで少しかかりますが、慣れるとscrollイベントを取得する従来の方法より、パフォーマンス改善にもつながるのでどんどん使っていきたいですね。

ポリフィルでIE11に対応できる点も大きいです。

以上、今回は【Intersection Observer API 】を使ってスクロールアニメーションを実装してみました。