スクロールアニメーションの実装

Framer Motion の基礎

日付:2025年3月1日

Framer Motion を使ったスクロールアニメーションの実装方法を解説。useInView を活用したフェードイン、useScroll を使った進捗バー、useTransform によるスクロール連動アニメーションを紹介します。

目 次

はじめに

Framer Motion では、スクロールイベントを利用したアニメーションを簡単に実装できます。
特に useInViewScrollTrigger を使うと、ページをスクロールしたときに要素をフェードインさせたり、進捗バーを作成することができます。

この記事では、スクロールに応じたアニメーションの実装方法 を詳しく解説します。

1. useInView を使ったスクロールアニメーション

useInView とは?

Framer Motion の useInView フックを使うと、要素が画面内に入ったときにアニメーションを発火 できます。

まずは、要素がスクロールで表示されたときにフェードインする基本的な実装を見てみましょう。

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

JSX
"use client"; import { motion, useInView } from "framer-motion"; import { useRef } from "react"; export default function ScrollFadeIn() { const ref = useRef(null); const isInView = useInView(ref, { once: true }); return ( <motion.div ref={ref} initial={{ opacity: 0, y: 50 }} animate={isInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.8, ease: "easeOut" }} className="p-6 bg-blue-500 text-white text-center rounded shadow" > スクロールでフェードイン </motion.div> ); }

解説

  • useRef(null) を定義し、対象の要素を参照
  • useInView(ref, { once: true })一度だけアニメーションを実行
  • animate={isInView ? { opacity: 1, y: 0 } : {}} で、要素が画面内に入ったらアニメーションを発火

2. スクロールに応じた進捗バー (ScrollProgress)

useScroll を使うと、ページ全体のスクロールの進捗を取得できます。
これを活用すると、スクロールの進行に合わせて動く進捗バーを作成できます。

スクロールに連動するプログレスバー

JSX
"use client"; import { motion, useScroll } from "framer-motion"; export default function ScrollProgressBar() { const { scrollYProgress } = useScroll(); return ( <motion.div style={{ scaleX: scrollYProgress }} className="fixed top-0 left-0 right-0 h-2 bg-red-500 origin-left" /> ); }

解説

  • useScroll()scrollYProgress を取得(0 ~ 1 の範囲)
  • scaleX: scrollYProgress を適用し、スクロール量に応じてバーの長さを変化
  • className="fixed top-0 left-0 right-0 h-2 bg-red-500 origin-left" で画面上部にバーを配置

これで、ページのスクロール量に応じて伸縮する進捗バーが作成できます!

3. ScrollTrigger を使ったアニメーション

要素がスクロールによって変化するアニメーションを作成するには、ScrollTrigger を使います。

画像のスケールアニメーション

JSX
"use client"; import { motion, useScroll, useTransform } from "framer-motion"; export default function ScrollScaleImage() { const { scrollYProgress } = useScroll(); const scale = useTransform(scrollYProgress, [0, 1], [1, 1.5]); return ( <motion.img src="/images/sample.jpg" alt="スクロールで拡大" style={{ scale }} className="w-full h-auto rounded shadow" /> ); }

解説

  • useScroll() でスクロール進捗を取得
  • useTransform(scrollYProgress, [0, 1], [1, 1.5]) で、スクロールに応じてスケール値を変化
  • motion.imgstyle={{ scale }} に適用し、スクロールに応じて画像が拡大するアニメーションを実装

まとめ

  • useInView → スクロールで要素が画面内に入ったらアニメーションを実行
  • useScroll → ページ全体のスクロール量を取得
  • useTransform → スクロール進捗に応じたアニメーションを作成
  • ScrollTrigger を使うと、よりダイナミックなアニメーションが可能

これらを活用すれば、スクロールに応じたリッチな UI アニメーションを実装できます。