【Vue.js】スクロールアニメーションの実装|Intersection Observer × トランジション

【Vue.js】スクロールアニメーションの実装|Intersection Observer × トランジション Vue.js

Webサイトで要素がスクロールに合わせて自然に表示される「スクロールアニメーション」は、ユーザー体験を向上させる効果があります。Vue.jsでは、Intersection Observer APIとVueのトランジション機能を組み合わせることで、軽量かつ高パフォーマンスな実装が可能です。本記事では、その具体的な方法を紹介します。

Intersection Observerで要素の表示タイミングを検知

Intersection Observer APIを使うことで、スクロールイベントを手動で監視せずに、要素がビューポートに入った瞬間を効率的に検出できます。

// composables/useIntersection.js
import { ref, onMounted, onUnmounted } from 'vue';

export function useIntersection(callback, options = {}) {
  const target = ref(null);
  let observer = null;

  onMounted(() => {
    observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          callback(entry);
        }
      });
    }, options);

    if (target.value) {
      observer.observe(target.value);
    }
  });

  onUnmounted(() => {
    if (observer && target.value) {
      observer.unobserve(target.value);
    }
  });

  return target;
}

トランジションを利用したアニメーション効果

Vueの<transition>コンポーネントを使うことで、要素が表示される際にフェードインやスライドインのアニメーションを付与できます。

<template>
  <transition name="fade-up">
    <div v-if="isVisible" ref="elementRef" class="box">
      スクロールで表示されるコンテンツ
    </div>
  </transition>
</template>

<script setup>
import { ref } from 'vue';
import { useIntersection } from './composables/useIntersection';

const isVisible = ref(false);

const elementRef = useIntersection(() => {
  isVisible.value = true;
});
</script>

<style>
.fade-up-enter-active {
  transition: all 0.6s ease-out;
}
.fade-up-enter-from {
  opacity: 0;
  transform: translateY(20px);
}
.fade-up-enter-to {
  opacity: 1;
  transform: translateY(0);
}
.box {
  background: #f2f2f2;
  padding: 20px;
  margin: 40px 0;
}
</style>

動作の流れ

上記のコードでは、コンポーネントがマウントされるとIntersection Observerが要素を監視します。要素が画面内に入るとコールバックが呼ばれ、isVisibletrueに変わって要素が描画されます。その描画時にVueのトランジションが適用され、フェードアップのアニメーションが実行されます。

パフォーマンス面のメリット

Intersection ObserverはネイティブAPIのため、高パフォーマンスでスクロール位置を監視できます。従来のscrollイベントのように頻繁なイベント発火を気にする必要がなく、モバイル環境でも軽快に動作します。

まとめ

Vue.jsでスクロールアニメーションを実装する際は、Intersection Observerと<transition>を組み合わせることで、シンプルかつ高パフォーマンスな表現が可能です。画像やテキスト、カードレイアウトなど様々な要素に応用できるので、ぜひUI改善に取り入れてみてください。