12k
All articles

GSAPのScrollTriggerアニメーションでUIに生命を吹き込む

GSAPのScrollTriggerプラグインを使い、スクラブ、ピン留め、視差効果など、スクロールに自然に反応するアニメーションを構築する方法を解説する。

OpenReplay Team
OpenReplay Team
GSAPのScrollTriggerアニメーションでUIに生命を吹き込む

スクロールベースのアニメーションは、静的なWebサイトを魅力的でインタラクティブな体験に変えることができます。CSSアニメーションは基本的な効果には有用ですが、洗練されたスクロール駆動アニメーションを作成するには、より強力なツールが必要です。GSAPのScrollTriggerプラグインはまさにそのツールであり、スクロール位置によってトリガーされる洗練されたパフォーマンスの高いアニメーションを作成できます。

このガイドでは、ユーザーのスクロールに自然に反応するScrollTriggerアニメーションの実装方法を、今日からプロジェクトで使える実用的な例とともに学習します。

重要なポイント

  • ScrollTriggerはアニメーションをスクロール位置に連動させ、インタラクティブな体験を提供
  • scrubを使用してアニメーションの進行をスクロール位置に直接連動
  • 要素をピン留めして高度なスクロールベースエフェクトを作成
  • startendを設定してアニメーションのトリガータイミングを精密に制御
  • 開発中はmarkersを使用してトリガーポイントを可視化

ScrollTriggerとは何か、なぜ使用するのか?

ScrollTriggerは、アニメーションをスクロール位置に連動させるGSAPプラグインです。要素がビューポートに入ったときに単純にアニメーションをトリガーする基本的な「on-scroll」ライブラリとは異なり、ScrollTriggerは以下の精密な制御を提供します:

  • スクロール位置に基づくアニメーションの開始・終了タイミング
  • ユーザーがスクロールするにつれてアニメーションがどのように進行するか(スクラビング)
  • ユーザーがスクロールしている間の要素のピン留め
  • 複雑なスクロールベースのインタラクションの作成

その結果は?単にトリガーされたときに再生されるのではなく、ユーザーのスクロールに連動して感じられるアニメーションです。

ScrollTriggerの基本設定

まず、基本的な設定を行いましょう:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ScrollTrigger Demo</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
        }
        
        section {
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .spacer {
            height: 100vh;
        }
        
        .box {
            width: 200px;
            height: 200px;
            background-color: #3498db;
            border-radius: 8px;
        }
    </style>
</head>
<body>
    <div class="spacer"></div>
    
    <section>
        <div class="box"></div>
    </section>
    
    <div class="spacer"></div>
    
    <!-- GSAP and ScrollTrigger -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
    
    <script>
        // Register the plugin
        gsap.registerPlugin(ScrollTrigger);
        
        // Your animations will go here
    </script>
</body>
</html>

基本的なScrollTriggerアニメーション

要素がビューポートに入ったときにトリガーされるシンプルなアニメーションから始めましょう:

gsap.to(".box", {
    scrollTrigger: ".box", // アニメーションをトリガーする要素
    x: 300, // 右に300px移動
    rotation: 360, // 360度回転
    duration: 1.5, // アニメーション時間
    ease: "power2.out" // イージング関数
});

このコードは、ボックスがビューポートに入ったときに移動と回転を行います。しかし、これは表面的な部分に過ぎません。

ScrollTrigger設定の理解

ScrollTriggerの全ての可能性を引き出すために、設定オプションを理解する必要があります:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box", // アニメーションをトリガーする要素
        start: "top center", // ボックスの上部がビューポートの中央に到達したときに開始
        end: "bottom center", // ボックスの下部がビューポートの中央に到達したときに終了
        toggleActions: "play pause reverse reset", // 進入、退出、再進入、再退出時のアクション
        markers: true, // デバッグ用のマーカーを表示(本番環境では削除)
    },
    x: 300,
    rotation: 360,
    duration: 2
});

startendプロパティは、アニメーションがアクティブになるタイミングと非アクティブになるタイミングを定義します。形式は"[トリガー要素の位置] [ビューポートの位置]"です。

toggleActionsは、4つの重要な瞬間でのアニメーションの動作を制御します:

  1. トリガー領域に入るとき
  2. トリガー領域から出るとき
  3. 上スクロール時にトリガー領域に再び入るとき
  4. 上スクロール時にトリガー領域から出るとき

オプションには:playpauseresumereverserestartresetcompletenoneがあります。

スクラブを使用したスクロール駆動アニメーションの作成

真の魔法はscrubプロパティで起こります。これはアニメーションの進行をスクロール位置に直接連動させます:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box",
        start: "top center",
        end: "bottom center",
        scrub: true, // アニメーションの進行をスクロール位置に連動
        markers: true
    },
    x: 300,
    rotation: 360,
    backgroundColor: "#e74c3c"
});

scrub: trueにより、アニメーションはユーザーのスクロールに合わせて進行し、上スクロール時には逆再生されます。よりスムーズなアニメーションには、scrub: 0.5のような数値を使用して軽い遅延を追加します。

スクロール中の要素のピン留め

ScrollTriggerの最も強力な機能の一つは、ユーザーがスクロールしている間に要素をその場に固定することです:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box",
        start: "center center",
        end: "+=300", // 開始位置から300px後に終了
        pin: true, // アニメーション中にボックスを固定
        scrub: 1,
        markers: true
    },
    x: 300,
    rotation: 360,
    scale: 1.5,
    backgroundColor: "#9b59b6"
});

これにより、アニメーションの再生中にボックスが固定され、パララックスのような効果が作成されます。end: "+=300"は、開始点から300ピクセルスクロールした後にアニメーションが終了することを意味します。

リビールアニメーションの作成

テキストや画像の実用的なリビールアニメーションを作成しましょう:

<div class="spacer"></div>

<section class="reveal-section">
    <div class="reveal-container">
        <h1 class="reveal-text">スクロール駆動アニメーション</h1>
        <p class="reveal-text">GSAP ScrollTriggerで魅力的なユーザー体験を作成</p>
    </div>
</section>

<div class="spacer"></div>
.reveal-section {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.reveal-container {
    max-width: 800px;
    text-align: center;
    overflow: hidden;
}

.reveal-text {
    opacity: 0;
    transform: translateY(50px);
}
// リビールアニメーション
gsap.utils.toArray('.reveal-text').forEach(text => {
    gsap.to(text, {
        scrollTrigger: {
            trigger: text,
            start: "top 80%", // テキストの上部がビューポートの上から80%の位置に来たときに開始
            toggleActions: "play none none none"
        },
        y: 0,
        opacity: 1,
        duration: 1,
        ease: "power2.out"
    });
});

これにより、各テキスト要素がビューポートに入るときにクリーンなリビール効果が作成されます。

パララックス効果の作成

パララックス効果はWebサイトに奥行きを追加します。作成方法は以下の通りです:

<div class="parallax-container">
    <div class="parallax-bg"></div>
    <div class="parallax-content">
        <h1>パララックス効果</h1>
    </div>
</div>
.parallax-container {
    height: 100vh;
    position: relative;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
}

.parallax-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 120%; /* 移動のための追加の高さ */
    background-image: url('your-background-image.jpg');
    background-size: cover;
    background-position: center;
}

.parallax-content {
    position: relative;
    z-index: 1;
    color: white;
    text-align: center;
}
// パララックス効果
gsap.to(".parallax-bg", {
    scrollTrigger: {
        trigger: ".parallax-container",
        start: "top bottom",
        end: "bottom top",
        scrub: true
    },
    y: -100, // スクロールに合わせて背景を100px上に移動
    ease: "none"
});

これにより、背景が前景とは異なる速度で移動するシンプルなパララックス効果が作成されます。

横スクロールセクション

横スクロールセクションの作成も印象的な効果の一つです:

<div class="spacer"></div>

<section class="horizontal-scroll">
    <div class="horizontal-container">
        <div class="panel">パネル 1</div>
        <div class="panel">パネル 2</div>
        <div class="panel">パネル 3</div>
        <div class="panel">パネル 4</div>
    </div>
</section>

<div class="spacer"></div>
.horizontal-scroll {
    overflow: hidden;
    height: 100vh;
}

.horizontal-container {
    display: flex;
    width: 400%; /* 100% × パネル数 */
    height: 100%;
}

.panel {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2rem;
}

.panel:nth-child(1) { background-color: #3498db; }
.panel:nth-child(2) { background-color: #2ecc71; }
.panel:nth-child(3) { background-color: #e74c3c; }
.panel:nth-child(4) { background-color: #9b59b6; }
// 横スクロール
gsap.to(".horizontal-container", {
    scrollTrigger: {
        trigger: ".horizontal-scroll",
        start: "top top",
        end: "+=3000", // スクロール距離
        pin: true,
        scrub: 1,
    },
    x: () => -(document.querySelector(".horizontal-container").offsetWidth - window.innerWidth),
    ease: "none"
});

これにより、ユーザーが縦にスクロールすると横にスクロールするセクションが作成されます。

パフォーマンス最適化のコツ

ScrollTriggerアニメーションは、適切に実装されていない場合、パフォーマンスに影響を与える可能性があります。以下にいくつかのコツを示します:

  1. will-changeを控えめに使用:実際にアニメーションする要素にのみ適用
  2. レイアウトプロパティのアニメーションを避ける:可能な限りtransformとopacityを使用
  3. 類似のアニメーションをバッチ処理gsap.utils.toArray()を使用して要素をループ処理
  4. 不要なScrollTriggerを削除:シングルページアプリケーションではscrollTrigger.kill()を使用
  5. マーカーの使用を減らす:本番環境ではmarkers: trueを削除

よくある問題のトラブルシューティング

アニメーションが早すぎる/遅すぎる開始

アニメーションが予期しないタイミングでトリガーされる場合は、startendの値を確認してください。markers: trueを使用してトリガーポイントを可視化します。

ぎくしゃくしたアニメーション

よりスムーズなアニメーションには、scrub: trueの代わりにscrub: 0.5以上を使用して軽い遅延を追加します。

モバイル互換性の問題

モバイルブラウザはスクロールイベントを異なって処理します。モバイルデバイスで十分にテストし、ScrollTrigger.matchMedia()を使用して異なる画面サイズに対して異なるアニメーションを作成することを検討してください。

まとめ

これらの技術により、ユーザーのインタラクションに自然に反応するスクロールアニメーションを作成でき、ユーザーを圧倒することなくUIを向上させることができます。シンプルな効果から始めて、ScrollTriggerの機能に慣れてきたら、より高度な技術を徐々に取り入れていきましょう。

よくある質問

ScrollTriggerはReact/Vue/Angularで動作しますか?

はい、ただしコンポーネントのマウント/アンマウント時にScrollTriggerインスタンスを適切に設定・クリーンアップする必要があります。

ScrollTriggerを他のアニメーションライブラリと併用できますか?

ScrollTriggerはGSAP用に設計されていますが、コールバック関数を使用して他のライブラリをトリガーできます。

ScrollTriggerアニメーションをレスポンシブにするにはどうすればよいですか?

位置指定にパーセンテージを使用し、ウィンドウリサイズ時にScrollTrigger.refresh()でScrollTriggerを更新します。

ScrollTriggerは無料で使用できますか?

基本機能は無料ですが、一部の高度な機能にはGreenSock Clubメンバーシップが必要です。

ScrollTriggerアニメーションをデバッグするにはどうすればよいですか?

markers: trueを使用してトリガーポイントを可視化し、コールバック関数でconsole.logを使用して進行状況を追跡します。

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers

We use cookies to improve your experience. By using our site, you accept cookies.