今回は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が扱えることはライブラリやフレームワークを使用していく上でも重要で基礎になる部分です。
積極的に使用していきましょう。