IntersectionObserverを使用したシンプルなアニメーション制御をComposition APIでやるには
IntersectionObserverを使用したシンプルなアニメーション制御をComposition APIでやるには
これは、Qiita Vue Advent Calendar 2023の20日目の記事です。
こんにちは、keigo です。今回は、画面スクロールによって要素が表示されたタイミングで、アニメーションを発火させるための実装を紹介します。
以下のようなものです。
IntersectionObserverとは
IntersectionObserverは、JavaScript APIのひとつです。 特定の要素がビューポート(ブラウザの表示領域)とどのように交差しているかを非同期的に監視するものです。
ref: https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserver
特定の要素がスクロールによって画面に描画されたタイミングで、特定の処理を発火させる
Vue3のComposition APIで実現するためには、以下のようなコードを書いていきます。
はじめに、イベント検出対象の要素に、ref属性を付与します。
<div ref="hoge" class="good-vibes-class">
そして、上記で付与したref属性の要素を取得し、onMountedでIntersectionObserver
を呼び出します。
const hoge = ref(); // 付与したref属性と同じ名前で宣言する
const handleIntersect = (entries: IntersectionObserverEntry[]) => {
if (entries[0].isIntersecting) {
// スクロールによって要素が描画されたとき
} else {
// 要素が描画されていないとき
}
}
onMounted(() => {
const observer = new IntersectionObserver(handleIntersect, {
root: null,
rootMargin: '0px',
threshold: 0
});
if (hoge.value) {
observer.observe(hoge.value);
}
})
アニメーションをつけるには
アニメーション対象の要素のcssに、transition
プロパティを付与します。
例:
.good-vibes-class {
transition: all 0.5s ease;
}
こうすることで、.good-vibes-class
にスタイルの変更が発生した場合は、0.5秒かけて変化過程が描画されます。
script側でスタイルを変更させるには、以下のように記述することで可能です。
const hoge = ref(); // 付与したref属性と同じ名前で宣言する
const animationTarget = document.getElementsByClassName('good-vibes-class');
const handleIntersect = (entries: IntersectionObserverEntry[]) => {
if (entries[0].isIntersecting) {
// 要素が画面に描画されると、横幅が0pxから100pxになる
(animationTarget[0] as HTMLElement).style.width = '100px';
} else {
(animationTarget[0] as HTMLElement).style.width = '0px';
}
}
onMounted(() => {
const observer = new IntersectionObserver(handleIntersect, {
root: null,
rootMargin: '0px',
threshold: 0
});
if (hoge.value) {
observer.observe(hoge.value);
}
})
おわりに
IntersectionObserver
を使用することで、要素が画面に描画されているかどうかを監視することができます。アニメーションのみならず、JavaScriptで発火可能な処理ならなんでも可能です。
どなたかの参考になれば幸いです!