スクロールに連動するアニメーションを実装する時は、JSのIntersection Observerを使用すると簡単に実装できる

スクロールに連動するアニメーションはIntersection Observerを使用すると、簡単に実装できます。カードUIがスクロールしてビューポートに表示されると、カード内の要素がアニメーションするUIを実装する方法を紹介します。

ライブラリなどは必要なく、数行のJavaScriptで簡単に実装できます。

Intersection Observerを使用してスクロールに連動するアニメーションを実装する方法を解説

Animate on scroll using Intersection Observer
by Keerthi

下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

はじめに

ポートフォリオサイトなどにアニメーションを使用することは、ビジターの目を引き付け、サイトに長く滞在してもらうための素晴らしい方法です。

この記事では、ビジターが下や上にスクロールしたときに動作する特別なタイプのアニメーションをサイトに追加する方法を解説します。スクロールに連動するアニメーションの実装にはIntersection Observerという機能を使用します。

デモのキャプチャ

スクロールしたときに動作するアニメーション

YouTubeでも解説しています!

Step 1: カードUIをHTMLとCSSで実装する

最初に、基本的なカードUIのHTMLマークアップとスタイリングをレイアウトしましょう。

外部CSSのstyle.cssは、下記のようになります。

上記のCSSでは、background-imageをグラデーションに設定しました。

ここまでの実装で、下記のように表示されます。

カードUIをHTMLとCSSで実装

カードUIをHTMLとCSSで実装

Step 2: CSSに基本的なアニメーションを追加する

次に、キーフレームアニメーションを使用してCSSにいくつかの基本的なアニメーションを追加しましょう。

上記のCSSには、2つのキーフレームアニメーションがあります。

  1. @keyframes animTitle {...}
  2. @keyframes animContent { ...}

キーフレームアニメーションは、CSSのセレクタで呼び出すことができます。

  1. .card h2 {animation: animTitle 2s infinite;}
  2. .card p{animation: animContent 2s infinite;}

上記のCSSでは、どちらも2秒間実行され、無限にループするように定義しています。これらのアニメーションは、要素の水平方向のx値に対する単純なトランジション/トランスレートです。

また、画像には伸縮アニメーションを追加します。CSSは下記の通りです。

このアニメーションは、Animistaというオンラインのアニメーションジェネレーターで作成しました。このジェネレーターでは、他のアニメーションを試すこともできます。使い方は簡単で、キーフレームのコードを生成してくれるので、それをアニメーションさせたいコンテナに適用するだけです(上記のように)。

ここまでの実装は、CodePenで確認できます。

See the Pen
scroll-animation-step2
by ui-code-tv (@ui-code-tv)
on CodePen.

ここまでは、CSSでアニメーションを制御していましたが、スクロールに連動するアニメーションを実装するにはJavaScriptを使用する必要があります。また、それに合わせてHTMLとCSSにもいくつかの変更が必要です。それが次の作業です。

Step 3: Intersection Observerを使用する前に、HTMLに変更を加える

JavaScriptでアニメーションを動作させる際にポイントとなるのが、アニメーションのキーフレーム関数名と適用すべきルールへのアクセスです。今回の実装では、下記のCSSルールで実現しています。

これをjavaScriptで動的に適用するには、これらのCSSを破棄し、HTMLのdata属性を使用して上記のアニメーション値を保存する必要があります。また、アニメーションさせる3つの要素には、.animateというクラスを付けます。したがって、カードのHTMLを下記のように変更します。

ここで重要なのはdata属性で、例えば、画像コンテナのdata属性は、data-animate="animImage 2s"となります。

ここでは、data-animateというdataアイテムを作成し、その値をcssで定義したアニメーションに設定しています。ちょっと不思議な感じがしますが、data属性の使い方についてはMozilla.orgをご覧ください。

また、スクロールしてアニメーションを起動できるように、さらにコンテンツを追加する必要があるので、カードのラッパーをさらに3つ複製します。

Step 4: JavaScriptのIntersection Observerを追加する

Intersection Observerは基本的には、指示された要素を観察します。対象となる要素と祖先の要素との交点(Intersection)の変化を観察します。先祖要素はブラウザのビューポートとし、交差を観察する対象要素はカードの3つの要素、すなわちimage, p, h2タグです。

Intersection Observer APIについは、下記をご覧ください。
参考: IntersectionObserverを使用すると実装が簡単に!Vue.jsでスクロールイベントをトリガーする方法

通常はルート要素を定義しますが、今回のケースでは、ブラウザのビューポートをデフォルトにしたいので、ルート要素を定義していないことに注意してください(ルート要素を定義しない場合、祖先をルートとみなします)。というわけで、今回のユースケースの基本的なコード構造は下記のようになります。

このコードをHTMLの中で、bodyタグ内の一番最後に追加します。簡単に説明すると、4つのステップがあります。

  1. Intersection Observerオブジェクトを作成する。
  2. 監視したいアイテムを照会して選択する。
  3. 選択したアイテムをIntersection Observerオブジェクトのウォッチリストに追加する。
  4. 交差イベントが発生するたびに何かを実行するコールバック関数を提供する。この場合、キーフレームアニメーションを添付する必要があります。

上記のコードでは、コールバック関数のコードを記述していません。これが次の作業となります。

Step 5: Intersection Observerのコールバック関数

このコールバックは、交差が発生するたびに呼び出されます。コールバックは、オブザーバーのリストにあるすべての要素にアクセスします。コールバックでは、どの要素が交差したかをループして調べます。そのためには、要素にあるisIntersectingというフラグをチェックします。if文を確認すると、これがわかります。

if (entry.isIntersecting) {...}

交差している場合は、キーフレームアニメーションを要素にアタッチし、次の行がそれを行います。

entry.target.style.animation = entry.target.dataset.animate

ここでは、要素のstyle.animationにStep 3で設定したdata-animateというdata属性を取得して設定します。例えば、画像の場合は、要素のマークアップのdata属性から文字列の部分を取得します。

<div class="image animate" data-animate="animImage 2s"></div>

この場合は、animImage 2sです。

コードのelseの部分は、アニメーションが交差していないため、アニメーションを削除します

これで前後にスクロールすると、アニメーションが再び実行されます。

完成

実際の動作は、下記のCodePenでご覧ください。

See the Pen
scroll-animation-step3
by ui-code-tv (@ui-code-tv)
on CodePen.

sponsors

top of page

©2021 coliss