MENU

【初心者向け】Intersection Observer APIを使用して、フェードインアニメーションを実装する方法

サキ

今回はWeb制作でよく目にする
フェードインアニメーションを解説していきます!

目次

作成するコードの全体像

今回作成するJavaScriptコードは以下になります。
.fadeとis-activeの部分を変更していただければコピペで使用可能です。

document.addEventListener('DOMContentLoaded', () => {

	const targets = document.querySelectorAll('.fade');

	const options = {
		threshold: 0.3,
	};

	const callback = (entries => {
	entries.forEach(entry => {
		if(entry.isIntersecting) {
			entry.target.classList.add('is-active');
			}
		});
	});

	const observer = new IntersectionObserver(callback, options);

	targets.forEach(target => {
		observer.observe(target);
	});
});

フェードインアニメーションとは

簡単に言うとスクロールするとコンテンツが下からふわっと現れたりするアレです。
フェードは映像編集の用語でフェードインが徐々に明るくなるような表現、フェードアウトが徐々に暗くなるような表現を指します。

今回は徐々に表示されるので、フェードインを実装することになります。

実装方法

今回の実装方法はスクロールした際に、要素が可視範囲に入ったかどうかをJavaScriptを使用して判定します。
その際にクラスを付与して、CSSでアニメーションを実装します。

では、実際に実装していきましょう。

実行タイミングの指定

今回は要素に対して処理を行うものなのでDOMContentLoadedで全体を囲って、実行タイミングを指定しましょう。
body閉じタグ直下で他の処理などがない場合などは記述不要ですが、今回は汎用的な場合を想定して念の為指定しておきます。

document.addEventListener('DOMContentLoaded', () => {

});

アニメーションさせたい要素を取得

まずはアニメーションさせたい要素を取得します。

const targets = document.querySelectorAll('.fade');

constで定数を定義します。
querySelectorAllを使用して、fadeというクラスを全て取得して定数targetsに格納します。

.fadeは特に意味はありませんので、必要なクラス名に変更して問題ありません。

オプションを設定

次にアニメーション範囲のオプションを設定します。
以下で3つの設定を紹介しますが、今回の最終的なコードではthresholdのみ使用して他は省略します。

const options = {
	root: null,
	rootMargin: '0px 0px 0px 0px',
	threshold: 0.3,
};

root

rootは範囲を指定します。
デフォルトはビューポートとなっており、指定をしない場合や、nullの場合にはビューポートになります。

他の範囲を指定したい場合は、要素を取得して指定します。

rootMargin

rootのマージン(余白)を指定します。
デフォルトは0でこの値で範囲を拡張、縮小することで調整します。

pxや%で指定が可能です。

threshold

こちらはrootに何%入ってきたらという指定になります。
例えばrootの30%としたい場合は0.3を指定します。

0〜1を指定することができ、1が100%として考えると30%であれば0.3となります。

実行する処理を設定

次に実行する処理を指定します。

const callback = (entries => {
	entries.forEach(entry => {
		if(entry.isIntersecting) {
		entry.target.classList.add('is-active');
		}
	});
});

今回はcallbackという関数に、アニメーションさせたい複数の要素をforEachで繰り返して同一の処理をします。
if文にあるentry.isIntersectingは交差状態だとtrueを返すので、こちらを使用して処理を実行します。

entry.targetで対象の要素を取得できるため、この要素に対してclassList.addでis-activeクラスを付与します。

事前設定はここまでで、実際にIntersection Observerを使用していきましょう。

Intersection Observer APIを設定

Intersection Observer API(インターセクションオブザーバーエーピーアイ)とは、JavaScriptの機能の一つで、要素がビューポート内に入ってきたかや、他の要素と交差したかを判断することが可能です。

以前はスクロールイベントで判断する方法が一般的でしたが、こちらを使用する方が無駄な処理が少なくて済むためフェードインにはこちらを使用して実装します。

使い方

new IntersectionObserverでインターセクションオブザーバーオブジェクトを作成します。
第一引数にはコールバック関数(先ほど作成したcallback)、第二引数にはオプション(先ほど作成したoptions)を指定します。

引数は今回事前に定義してから指定してますが、直接指定しても問題はありません。

const observer = new IntersectionObserver(callback, options);

最後にこちらを実行する処理としてobserveメソッドを要素に対して実行します。
これで監視が実行されます。

targets.forEach(target => {
	observer.observe(target);
});

これでJavaScript側の処理は完了となります。

CSSアニメーションの設定

CSS側の設定をしていきます。


事前に透過(opacity)を0、位置変形で縦に100pxほど下に配置しておきます。
また、それぞれにアニメーションの速度とアニメーションの動作を指定しておきます。

次にis-activeクラスが付いたら、透過度を1にして表示、位置を元の位置0に戻すことで下から上がってくるようなアニメーションを再現します。

こちらの値はサンプルになりますので好きに変更して、自身の好みのアニメーションにしてください。

.fade {
	opacity: 0;
	transform: translateY(100px);
	transition: opacity 0.3s ease-out, transform 0.6s ease-out;
}
.fade.is-active {
	opacity: 1;
	transform: translateY(0);
}

最終的なコードは以下となります。

.fade {
	opacity: 0;
	transform: translateY(100px);
	transition: opacity 0.3s ease-out, transform 0.6s ease-out;
}
.fade.is-active {
	opacity: 1;
	transform: translateY(0);
}
document.addEventListener('DOMContentLoaded', () => {
	const targets = document.querySelectorAll('.fade');

	const options = {
		threshold: 0.3,
	};

	const callback = (entries => {
	entries.forEach(entry => {
		if(entry.isIntersecting) {
			entry.target.classList.add('is-active');
			}
		});
	});

	const observer = new IntersectionObserver(callback, options);

	targets.forEach(target => {
		observer.observe(target);
	});
});

実装方法については以上となります。

お疲れ様でした!

なぜスクロールイベントで実装しないのか

スクロールイベントではスクロールする度にイベントが発生していまい、処理が重くなってしまう場合があります。

Intersection Observer APIでは目的に合わせて最適化されているため、必要な場合のみ処理が実行されるのでパフォーマンスの面でこちらを採用することが多いです。

最後に

今回はIntersection Observer APIを使用したアニメーション手法についてご紹介しました。

jQueryなどを使用していると直感的ではないかもしれませんが、素のJavaScriptが扱えることはライブラリやフレームワークを使用していく上でも重要で基礎になる部分です。

積極的に使用していきましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次