スクロールで見せる(Scroll Reveal)
スクロールに連動して要素をアニメーションさせる実装をFramer Motion / React Spring / GSAP / Intersection Observer APIで比較
読み込み中...
'use client';
import { useRef } from 'react';
import { motion } from 'framer-motion';
export default function ScrollDemo() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div ref={containerRef} style={{ height: '400px', overflowY: 'auto' }}>
{/* フェードイン */}
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
viewport={{ once: true, amount: 0.3, root: containerRef }}
>
フェードイン
</motion.div>
{/* スライドイン(下から) */}
<motion.div
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
viewport={{ once: true, amount: 0.3, root: containerRef }}
>
スライドイン
</motion.div>
{/* スケールイン */}
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
viewport={{ once: true, amount: 0.3, root: containerRef }}
>
スケールイン
</motion.div>
{/* スタガー(複数要素を順番に) */}
{[0, 1, 2].map((i) => (
<motion.div
key={i}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: i * 0.1 }}
viewport={{ once: true, root: containerRef }}
>
スタガー {i + 1}
</motion.div>
))}
</div>
);
}jQueryで書くとこうなる
whileInView・React Spring の useSpring・GSAP の ScrollTrigger・ブラウザネイティブの IntersectionObserver を使うことで、より効率的にスクロールで見せるアニメーションを実装できます。// scroll イベントで要素の位置を判定してアニメーション
$(window).on('scroll', function () {
$('.animate-on-scroll').each(function () {
const elementTop = $(this).offset().top;
const viewportBottom = $(window).scrollTop() + $(window).height();
if (elementTop < viewportBottom - 50) {
$(this).addClass('is-visible');
}
});
});
// waypoints プラグインを使った方法
$('.animate-on-scroll').waypoint(function () {
$(this.element).addClass('is-visible');
}, { offset: '80%' });
// スクロール量に連動して透明度を変える
$(window).on('scroll', function () {
const scrollTop = $(window).scrollTop();
const opacity = Math.min(scrollTop / 300, 1);
$('#hero').css('opacity', 1 - opacity);
});実装方法の比較
| 項目 | Framer Motion | React Spring | GSAP | Intersection Observer |
|---|---|---|---|---|
| 記述量 | whileInViewで1要素に数行 | useSpring + IntersectionObserverで各要素にフック | ScrollTriggerで各要素に数行(DOMをquerySelectorで取得) | useRef + useEffectのセットアップが必要 |
| スクロール量連動 | useScroll + useTransformで簡単に実現 | useScrollフック(@react-spring/web)で実現可能 | ScrollTrigger scrubオプションで簡単に実現 | 自前でscrollイベント + 計算が必要 |
| onceオプション | viewport={{ once: true }}で一度だけ実行 | IntersectionObserver内でdisconnect()を呼ぶ | toggleActions: 'play none none none'で一度だけ実行 | disconnect()で手動解除が必要 |
| パフォーマンス | 内部でIntersectionObserverを使用 | IntersectionObserver + 物理スプリング計算 | 高度に最適化されたScrollTrigger API | ネイティブAPIで軽量 |
| 設定コスト | 高:framer-motionのインストールが必要 | 高:@react-spring/webのインストールが必要 | 中:gsap + @gsap/reactのインストールが必要 | 低:追加ライブラリ不要 |
whileInView のポイント
- •
viewport={{ once: true }}で一度表示されたら再度アニメーションしない - •
viewport={{ amount: 0.3 }}で要素の30%が見えたときにトリガー - • スクロール可能なコンテナ内で使う場合は
viewport={{ root: containerRef }}を指定する - •
useScroll+useTransformでスクロール量に応じた連続的な値変化が可能 - • jQueryの
$(window).on('scroll')と違いメインスレッドをブロックしない
🤖 AIプロンプトテンプレート
Next.js + Framer Motion でスクロールで見せるアニメーションを実装してください。
- 要素がビューポートに入ったときにフェードイン+スライドアップ
- whileInView と viewport={{ once: true }} を使用
- 複数の要素が順番に現れるスタガー効果も加える
- TypeScript / Tailwind CSS v4 を使用⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
React Spring のポイント
- •
useSpring(反応型)とIntersectionObserverを組み合わせると、ビューポート進入時にスプリングアニメーションが起動する - •
@react-spring/webにはuseScrollフックがあり、スクロール量に連動した値変化を実装できる - • 複数要素をアニメーションさせる場合は各要素を独立したコンポーネントに分けてそれぞれ
useSpringを持たせる - • スプリング物理により、ビューポート進入時のアニメーションにオーバーシュートのような自然な動きを加えられる
🤖 AIプロンプトテンプレート
Next.js + React Spring でスクロールで見せるアニメーションを実装してください。 - useSpring と IntersectionObserver を組み合わせて実装 - 要素がビューポートに入ったときにフェードイン+スライドアップ - 複数要素を個別コンポーネントに分けてそれぞれフックを持たせる - 使用ライブラリ: @react-spring/web - TypeScript / Tailwind CSS v4 を使用
⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
GSAP ScrollTrigger のポイント
- •
gsap.registerPlugin(useGSAP, ScrollTrigger)でプラグインを登録してから使用する - •
scrollTrigger.scrollerにコンテナのrefを渡すと、ページ全体ではなく特定コンテナ内のスクロールに連動できる - •
toggleActions: 'play none none none'は「進入時に再生・それ以外は何もしない」という意味で一度だけ実行される(Framer のonce: true相当) - •
scrub: trueを追加するとスクロール量に連動してアニメーションが進む(パーラックス効果など) - •
useGSAPでセットアップしたScrollTriggerはコンポーネントのアンマウント時に自動でクリーンアップされる
🤖 AIプロンプトテンプレート
Next.js + GSAP ScrollTrigger でスクロールで見せるアニメーションを実装してください。 - useGSAP フックでスクロールコンテナ内の要素を querySelectorAll で取得 - gsap.fromTo() と ScrollTrigger でビューポート進入時にフェードイン+スライドアップ - toggleActions: 'play none none none' で一度だけアニメーションを実行 - scroller オプションでカスタムスクロールコンテナを指定する - 使用ライブラリ: gsap, @gsap/react - TypeScript / Tailwind CSS v4 を使用
⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
スクロールで見せる(Scroll Reveal)は、ページのスクロール量や要素のビューポート進入に連動して発動するアニメーション効果。
ランディングページのセクション表示・データの積み上げアニメーション・プログレスバーの進捗表示・パララックス背景など、スクロールをインタラクションとして活用する場面で使われる。
- •スクロール進入でフェードイン型(IntersectionObserver)
- •パララックス型(スクロール量に比例して移動)
- •スクロールプログレス型(進行率バー)
- •スクロールトリガーアニメーション型(GSAP ScrollTrigger)
- •スティッキーアニメーション型
同じカテゴリの他のページ
文字を演出する(Text Animation)| UI Memo
GSAPのSplitText・ScrambleTextで実装する文字アニメーションのサンプル。1文字ずつフェード・スライド・波・スクランブル・バラけて再集合など、テキスト演出のUIパターン実例集。
動きの質感を選ぶ(Easing)
イージングの違いを体験で比較。power・back・bounce・elasticなどGSAP・Framer Motion・CSS Transitionのeaseを一覧・比較できるUIパターン実例集。
スクロールで物語る(Scroll Storytelling)
GSAPのScrollTriggerで実装するスクロール演出のサンプル。scrub・pin・横スクロール・パララックスなど、スクロールに連動した高度なアニメーションのUIパターン実例集。デモ・コード付き。