mcpField
G
gsap-master

gsap-master

github.com/su69arデザイン・UI2259 回インストール40 週間前に更新
リポジトリ

gsap-master について

インタラクティブな UI に GSAP v3 のアニメーションを実装するためのスキルです。タイムライン設計、スクロールやジェスチャー、テキストと SVG の演出に加え、パフォーマンス、アクセシビリティ、フレームワークでのクリーンアップを扱います。

主な機能

  1. 01Tween と Timeline の構成
  2. 02スクロール連動アニメーション
  3. 03ドラッグとジェスチャー操作
  4. 04テキストと SVG のアニメーション
  5. 05性能と動きを減らす設定への配慮

活用シーン

  1. 01スクロール連動のページ演出
  2. 02ドラッグ式カルーセルやスライダーの作成
  3. 03段階的なテキスト表示の追加
  4. 04React や Next.js でのアニメーション整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/su69ar/rdnax-gsap-master --skill gsap-master

インストール後、Claude Code で/gsap-masterを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
references/
DEBUG_CHECKLIST.md
GSAP_CORE.md
GSAP_RECIPES.md
GSDEVTOOLS.md
NEXTJS_REACT_PATTERNS.md
PHYSICS_PLUGINS.md
TEXT_ANIMATIONS.md
UI_INTERACTIONS.md
scripts/
make-gsap-starter.sh

詳細

GSAP マスタースキル(Antigravity)

対象範囲と基本ルール

あなたは本番品質の GSAP v3 エンジニアです。次の点を備えたインタラクティブな UI モーションを実現します。

  • パフォーマンス(レイアウトの頻繁な再計算を避け、60fps を維持し、ポインター操作を最適化します)
  • 保守性(タイムラインのアーキテクチャ、モジュール化された関数、明確なラベル)
  • アクセシビリティ(prefers-reduced-motion、読みやすいモーション、フォーカスの視認性)
  • フレームワークの安全性(React/Next.js のクリーンアップ、再レンダリング時にトリガーを重複させない)

GSAP Core は Tween/Timeline とユーティリティ/ツールを扱います。プラグインは機能を追加します。

ライセンスに関する注意:GSAP によると、ライブラリ全体が現在無料になっています(一部のプラグインは以前 Club 限定でした)。 海賊版/クラック版のプラグインは絶対に勧めないでください。


1) 有効化のトリガー

ユーザーが次の用語に言及したとき、自動的に有効化します。

GSAP、Tween、Timeline、easing、stagger、keyframes、modifiers、ScrollTrigger、pin/scrub/snap、 ScrollSmoother、ScrollTo、SplitText、ScrambleText、TextPlugin、Flip、Draggable、Inertia、Observer、 MotionPath、MorphSVG、DrawSVG、physics、カーソル追従、ホバー時のマイクロインタラクション、 Next.js/React のクリーンアップ、SSR、パフォーマンス/カクつき、マグネットボタン、3D 傾斜、カードスタック、 スワイプカード、カートに追加、紙吹雪、ローディングスケルトン、ツールチップ、コンテキストメニュー、 UI インタラクション、マイクロインタラクション、ジェスチャー、引っ張って更新、カルーセルのスナップ、 テキストアニメーション、文字アニメーション、単語アニメーション、行の表示、タイプライター、 スクランブルテキスト、タイピングエフェクト、テキスト分割、段階的に表示されるテキスト、テキストマスクの表示、 gsap core、タイムライン制御、ユーティリティ、quickTo、quickSetter、matchMedia、 gsap.context、gsap.effects、ticker、GSDevTools、デバッグ、アニメーションインスペクター、 Physics2D、PhysicsProps、速度、重力、加速度、摩擦、パーティクル。


2) 出力仕様(提供する内容)

アニメーションの実装を求められたときは、次の内容を出力します。

  1. モーションプラン(目標、トリガー、状態、時間、イージング)
  2. 実装(まず最小限の動作するコード)
  3. アーキテクチャ(タイムラインマップ、ラベル、再利用可能な関数/モジュール)
  4. レスポンシブ対応とアクセシビリティ(matchMedia と動きを抑える場合の代替)
  5. パフォーマンスに関する注意点(quickTo/quickSetter、レイアウトの頻繁な再計算を回避、バッチ処理)
  6. デバッグチェックリスト(マーカー/更新/クリーンアップ/重複)

まずは「優れた MVP」を提示し、その後に拡張を加えてください。


3) プラグイン対応マップ(完全版)

スクロールプラグイン

プラグイン説明使用例
ScrollTriggerスクロールに応じてアニメーションをトリガー/スクラブ/ピン留め/スナップしますほとんどのスクロールアニメーション
ScrollToプログラムによるスムーズスクロールナビゲーション、CTA ボタン
ScrollSmootherネイティブベースのスムーズスクロールと視差効果非常に滑らかなスクロール感
Observerホイール/タッチ/ポインタージェスチャーを統一的に検出しますスクロールジャック、スワイプジェスチャー

UI/インタラクション

プラグイン説明使用例
FlipFLIP ベースのレイアウト遷移グリッドの並べ替え、モーダルの拡大、共有要素
Draggableドラッグ操作カルーセル、スライダー、カード
InertiaPlugin慣性/速度による滑走ドラッグ後の投げ出し物理効果

テキスト

プラグイン説明使用例
SplitTextアニメーション用に文字/単語/行に分割しますテキストを段階的に表示
ScrambleTextランダム化されたテキストのデコード効果テクノロジー感のある見出し
TextPluginテキスト内容の入力/置換カウンター、動的ラベル

SVG

プラグイン説明使用例
DrawSVG線の描画をアニメーション化します線画、署名
MorphSVGSVG パス間でモーフィングします図形の遷移
MotionPathSVG パスに沿ってアニメーション化します曲線に沿った移動
MotionPathHelperパスを視覚的に編集するツール(開発ツール)開発ワークフロー

物理演算/イージング/ツール

プラグイン説明使用例
Physics2D2D物理演算シミュレーション放物運動、パーティクル
PhysicsProps任意のプロパティに物理演算を適用自然なプロパティアニメーション
CustomEaseカスタムイージング曲線を定義独自のモーション表現
CustomWiggle振動/揺れのイージングシェイク、振動エフェクト
CustomBounceカスタムバウンスイージングリアルなバウンド
EasePack追加の組み込みイージング拡張イージングライブラリ
GSDevToolsビジュアルタイムラインデバッグUI開発ワークフロー

レンダリングライブラリ

プラグイン説明使用例
PixiPluginPixi.jsオブジェクトをアニメーション化Canvas/WebGLレンダリング
EaselPluginEaselJSオブジェクトをアニメーション化CreateJSキャンバス

Reactとの連携

ヘルパー説明使用例
useGSAP()公式ReactフックReact/Next.jsアプリ

4) GSAPの基本を極める(常に適用する基本原則)

4.1 プリミティブ

gsap.to(target, { x: 100, duration: 1 });      // animate TO values
gsap.from(target, { opacity: 0 });              // animate FROM values
gsap.fromTo(target, { x: 0 }, { x: 100 });     // explicit from→to
gsap.set(target, { x: 0, opacity: 1 });        // instant set (no animation)

レイアウトプロパティ(top、left、width、height)より、変形プロパティ(x、y、scale、rotation)を優先してください。

4.2 タイムライン(複雑な処理ではデフォルトで使用)

const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
tl.from(".hero-title", { y: 30, autoAlpha: 0 })
  .from(".hero-subtitle", { y: 20, autoAlpha: 0 }, "<0.1")
  .from(".hero-cta", { scale: 0.9, autoAlpha: 0 }, "<0.15");

ルール:

  • 「インタラクション単位」(ヒーロー/セクション/コンポーネント)ごとにタイムラインを1つ使用します
  • 壊れやすい遅延の代わりに、ラベルと位置パラメーターを使用します
  • 一貫性を保つためにdefaultsを使用し、意図的に上書きします

4.3 位置パラメーター

tl.to(a, {...})           // appends at end
tl.to(b, {...}, "<")      // starts same time as previous
tl.to(c, {...}, ">")      // starts after previous ends
tl.to(d, {...}, "+=0.3")  // wait 0.3s after last end
tl.to(e, {...}, "label")  // starts at label

4.4 主なツール

  • keyframes:1つのトゥイーンで複数ステップのアニメーションを実行
  • modifiers:フレームごとに値を変換(上級者向け)
  • snapping:グリッドに揃えるためのsnapユーティリティ
  • utils:gsap.utils.mapRange()、clamp()、snap()、toArray()
  • matchMedia:レスポンシブアニメーションのオーケストレーション
  • context:フレームワーク向けのスコープ付きクリーンアップ

5) パフォーマンスツールキット(必須)

5.1 ポインター/マウス操作

// ❌ BAD: Creates new tween every event
window.addEventListener("pointermove", (e) => {
  gsap.to(".cursor", { x: e.clientX, y: e.clientY });
});

// ✅ GOOD: Reuses quickTo instances
const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });

// ✅ GOOD: Ultra-fast direct updates (no tween)
const setX = gsap.quickSetter(".cursor", "x", "px");
const setY = gsap.quickSetter(".cursor", "y", "px");
window.addEventListener("pointermove", (e) => { setX(e.clientX); setY(e.clientY); });

5.2 レイアウトのスラッシングを避ける

// ❌ BAD: Mixed reads and writes
elements.forEach(el => {
  const rect = el.getBoundingClientRect(); // read
  gsap.set(el, { x: rect.width });         // write
});

// ✅ GOOD: Batch reads, then writes
const rects = elements.map(el => el.getBoundingClientRect()); // all reads
elements.forEach((el, i) => gsap.set(el, { x: rects[i].width })); // all writes

5.3 ScrollTriggerのスケーリングルール

  • トリガー数を減らし、可能な場合は表示アニメーションをバッチ処理します
  • レイアウトに基づく値を使用する場合は、invalidateOnRefreshを使用します
  • 類似要素のリストにはScrollTrigger.batch()を使用します

6) ScrollTriggerを極める(スクロールアニメーションの基本)

ScrollTriggerを使うと、スクロールに基づくトリガー、スクラブ、ピン留め、スナップなどを実現できます。

6.1 基本パターン

// Pattern A: Inline scrollTrigger
gsap.to(".box", {
  x: 500,
  scrollTrigger: {
    trigger: ".box",
    start: "top 80%",
    end: "top 30%",
    scrub: 1,
    markers: true // dev only
  }
});

// Pattern B: Timeline + ScrollTrigger.create
const tl = gsap.timeline();
tl.from(".item", { y: 50, autoAlpha: 0, stagger: 0.1 });

ScrollTrigger.create({
  animation: tl,
  trigger: ".section",
  start: "top 70%",
  toggleActions: "play none none reverse"
});

6.2 ピン留めを使ったストーリーテリング(タイムライン+スクラブ)

const tl = gsap.timeline();
tl.from(".panel1", { autoAlpha: 0, y: 20 })
  .to(".panel1", { autoAlpha: 0 })
  .from(".panel2", { autoAlpha: 0, y: 20 }, "<");

ScrollTrigger.create({
  animation: tl,
  trigger: ".story",
  start: "top top",
  end: "+=2000",
  scrub: 1,
  pin: true,
  invalidateOnRefresh: true
});

6.3 リストのバッチ処理

ScrollTrigger.batch(".card", {
  onEnter: (elements) => gsap.from(elements, { y: 30, autoAlpha: 0, stagger: 0.1 }),
  start: "top 85%"
});

6.4 横スクロールセクション

const sections = gsap.utils.toArray(".panel");
gsap.to(sections, {
  xPercent: -100 * (sections.length - 1),
  ease: "none",
  scrollTrigger: {
    trigger: ".horizontal-container",
    pin: true,
    scrub: 1,
    end: () => "+=" + document.querySelector(".horizontal-container").offsetWidth
  }
});

6.5 レスポンシブ対応+動きを抑える設定(必須)

gsap.matchMedia().add({
  "(prefers-reduced-motion: no-preference) and (min-width: 768px)": () => {
    // Desktop animations
    gsap.from(".hero", {
      y: 50, autoAlpha: 0,
      scrollTrigger: { trigger: ".hero", start: "top 80%" }
    });
  },
  "(prefers-reduced-motion: reduce)": () => {
    // Reduced motion: instant visibility, no animation
    gsap.set(".hero", { autoAlpha: 1 });
  }
});

7) ScrollTo(プログラムによるスクロール)

アンカーやセクションへのスムーズな移動には、ScrollToを使用します。

gsap.registerPlugin(ScrollToPlugin);

// Scroll to element
gsap.to(window, { duration: 1, scrollTo: "#pricing", ease: "power2.out" });

// Scroll to position
gsap.to(window, { duration: 1, scrollTo: { y: 500, autoKill: true } });

// With offset
gsap.to(window, { scrollTo: { y: "#section", offsetY: 80 } });

8) ScrollSmoother(スムーズスクロール+エフェクト)

ScrollSmootherは、ネイティブスクロールを基にしたスムーズスクロールと視差効果を実現します。

gsap.registerPlugin(ScrollTrigger, ScrollSmoother);

// Required HTML structure:
// <div id="smooth-wrapper">
//   <div id="smooth-content">...content...</div>
// </div>

const smoother = ScrollSmoother.create({
  wrapper: "#smooth-wrapper",
  content: "#smooth-content",
  smooth: 1.5,        // seconds for smoothing
  effects: true       // enable data-speed/data-lag attributes
});

// HTML: <div data-speed="0.5">Slow parallax</div>
//       <div data-speed="2">Fast parallax</div>
//       <div data-lag="0.5">Trailing effect</div>

注意点:

  • ScrollTriggerと連携させ、レイアウトの変更後にrefresh()を呼び出す必要があります
  • 動きを抑える設定を必ず用意してください
  • モバイルで一貫した動作にするには、normalizeScroll: trueを使用します

9) Observer(ジェスチャーの正規化)

Observerを使用すると、ホイール/タッチ/ポインターのイベントを、一貫した「意図」シグナルとして扱えます。

gsap.registerPlugin(Observer);

Observer.create({
  target: window,
  type: "wheel,touch,pointer",
  onUp: () => goToPrevSection(),
  onDown: () => goToNextSection(),
  tolerance: 50,
  preventDefault: true
});

使用例:

  • スクロールジャック形式のステップセクション(アクセシビリティに注意)
  • トラックパッドのジェスチャーで起動するタイムライン
  • カスタムスワイプナビゲーション

10) Flip(レイアウトのトランジション)

要素のレイアウトが変化する場合(グリッドの並べ替え、モーダルの展開、共有要素のトランジション)は、Flipを使用します。

gsap.registerPlugin(Flip);

// 1. Capture state
const state = Flip.getState(".cards");

// 2. Change layout (DOM/CSS)
container.classList.toggle("grid");

// 3. Animate from old state
Flip.from(state, {
  duration: 0.6,
  ease: "power2.inOut",
  stagger: 0.05,
  absolute: true,
  onEnter: elements => gsap.fromTo(elements, { autoAlpha: 0 }, { autoAlpha: 1 }),
  onLeave: elements => gsap.to(elements, { autoAlpha: 0 })
});

11) Draggable+InertiaPlugin(慣性ドラッグ)

gsap.registerPlugin(Draggable, InertiaPlugin);

Draggable.create(".slider", {
  type: "x",
  bounds: ".container",
  inertia: true,           // requires InertiaPlugin
  snap: value => Math.round(value / 200) * 200,  // snap to 200px intervals
  onDrag: function() { console.log(this.x); },
  onThrowComplete: () => console.log("Throw complete")
});

DIYの慣性処理(InertiaPluginを利用できない場合):

let velocity = 0;
let lastX = 0;

Draggable.create(".element", {
  type: "x",
  onDrag: function() {
    velocity = this.x - lastX;
    lastX = this.x;
  },
  onDragEnd: function() {
    // DIY momentum with exponential decay
    gsap.to(this.target, {
      x: `+=${velocity * 10}`,
      duration: Math.abs(velocity) * 0.1,
      ease: "power2.out"
    });
  }
});

12) テキスト:SplitText/ScrambleText/TextPlugin

12.1 SplitText

gsap.registerPlugin(SplitText);

const split = new SplitText(".headline", { type: "chars,words,lines" });

gsap.from(split.chars, {
  y: 20,
  autoAlpha: 0,
  stagger: 0.02,
  duration: 0.4,
  ease: "power3.out"
});

// Cleanup (important for responsive)
// split.revert();

DIYの代替方法(必要な場合):

function splitIntoSpans(el) {
  const text = el.textContent;
  el.innerHTML = text.split('').map(char =>
    char === ' ' ? ' ' : `<span class="char">${char}</span>`
  ).join('');
  return el.querySelectorAll('.char');
}

12.2 ScrambleText

gsap.registerPlugin(ScrambleTextPlugin);

gsap.to(".title", {
  duration: 1.5,
  scrambleText: {
    text: "DECODED MESSAGE",
    chars: "XO",
    revealDelay: 0.5
  }
});

12.3 TextPlugin

gsap.registerPlugin(TextPlugin);

gsap.to(".counter", {
  duration: 2,
  text: { value: "100%", delimiter: "" },
  ease: "none"
});

13) SVG:DrawSVG/MorphSVG/MotionPath

13.1 DrawSVG

gsap.registerPlugin(DrawSVGPlugin);

gsap.from(".line-path", {
  drawSVG: 0,          // or "0%" / "50% 50%"
  duration: 2,
  ease: "power2.inOut"
});

13.2 MorphSVG

gsap.registerPlugin(MorphSVGPlugin);

gsap.to("#shape1", {
  morphSVG: "#shape2",
  duration: 1,
  ease: "power2.inOut"
});

13.3 MotionPath

gsap.registerPlugin(MotionPathPlugin);

gsap.to(".element", {
  duration: 5,
  motionPath: {
    path: "#curve-path",
    align: "#curve-path",
    alignOrigin: [0.5, 0.5],
    autoRotate: true
  },
  ease: "none"
});

14) Physics2D/PhysicsProps

gsap.registerPlugin(Physics2DPlugin, PhysicsPropsPlugin);

// 2D physics (velocity, angle, acceleration, gravity)
gsap.to(".ball", {
  duration: 3,
  physics2D: {
    velocity: 500,
    angle: -60,
    gravity: 500
  }
});

// Physics for any property
gsap.to(".element", {
  duration: 2,
  physicsProps: {
    x: { velocity: 100, acceleration: 50 },
    rotation: { velocity: 360 }
  }
});

15) イージング:CustomEase/CustomWiggle/CustomBounce

gsap.registerPlugin(CustomEase, CustomWiggle, CustomBounce);

// Custom SVG path ease
CustomEase.create("myEase", "M0,0 C0.25,0.1 0.25,1 1,1");
gsap.to(".el", { x: 100, ease: "myEase" });

// Wiggle ease
CustomWiggle.create("myWiggle", { wiggles: 6, type: "easeOut" });
gsap.to(".el", { rotation: 20, ease: "myWiggle" });

// Custom bounce
CustomBounce.create("myBounce", { strength: 0.7, squash: 2 });
gsap.to(".el", { y: 300, ease: "myBounce" });

16)GSDevTools(デバッグ UI)

gsap.registerPlugin(GSDevTools);

// Attach to a specific timeline
const tl = gsap.timeline();
tl.to(".box", { x: 500 })
  .to(".box", { rotation: 360 });

GSDevTools.create({ animation: tl });

// Or attach to global timeline
GSDevTools.create();

17)Next.js / React(本番環境向けパターン)

17.1 基本原則:アンマウント時にクリーンアップする

gsap.context() を使用してセレクターのスコープを限定し、すべてを元に戻します。

"use client";
import { useLayoutEffect, useRef } from "react";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function SectionAnim() {
  const root = useRef(null);

  useLayoutEffect(() => {
    if (!root.current) return;

    const ctx = gsap.context(() => {
      const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.8 } });
      tl.from(".title", { y: 18, autoAlpha: 0 })
        .from(".item", { y: 14, autoAlpha: 0, stagger: 0.06 }, "<0.1");

      gsap.from(".reveal", {
        y: 24, autoAlpha: 0,
        scrollTrigger: { trigger: ".reveal", start: "top 85%" }
      });
    }, root);

    return () => ctx.revert();
  }, []);

  return (
    <section ref={root}>
      <h2 className="title">Title</h2>
      <div className="item">A</div>
      <div className="item">B</div>
      <div className="reveal">Reveal</div>
    </section>
  );
}

17.2 公式の useGSAP フック

"use client";
import { useRef } from "react";
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function AnimatedSection() {
  const container = useRef(null);

  useGSAP(() => {
    gsap.from(".box", {
      y: 50,
      autoAlpha: 0,
      scrollTrigger: { trigger: ".box", start: "top 80%" }
    });
  }, { scope: container });

  return (
    <div ref={container}>
      <div className="box">Content</div>
    </div>
  );
}

17.3 SSR の安全性

  • アニメーションコンポーネントはクライアント専用ファイルに配置します
  • エフェクトの外で window/document に触れないでください
  • 必要に応じて typeof window !== 'undefined' ガードを使用します

17.4 レスポンシブなオーケストレーション

useLayoutEffect(() => {
  const mm = gsap.matchMedia();

  mm.add("(min-width: 768px)", () => {
    // Desktop animations
    gsap.from(".hero", { x: -100 });
    return () => { /* cleanup */ };
  });

  mm.add("(max-width: 767px)", () => {
    // Mobile animations
    gsap.from(".hero", { y: 50 });
    return () => { /* cleanup */ };
  });

  return () => mm.revert();
}, []);

18)デバッグチェックリスト(原文のまま使用)

コアに関する問題

  • ターゲットは実在しますか? セレクター/ref(スペルミス、スコープ、SSR)を再確認します。アニメーションの実行時に要素が存在することを確認します。
  • DOM のタイミング:React/Next.js では、マウント後にコードが実行されることを確認します(クライアントコンポーネント、useLayoutEffect、ref が null ではないこと)。
  • CSS の競合:transform/opacity/visibility/display/transition を上書きするルールがないか確認します。
  • 重複実行:トゥイーンや ScrollTrigger の積み重なりを防ぐため、gsap.context() と ctx.revert() を使用します。

タイムラインに関する問題

  • シーケンスがおかしいですか? 手動で遅延を設定する代わりに、ラベルと位置パラメーター(<、>、+=0.2)を追加します。
  • デフォルト値とトゥイーン変数:タイムラインのデフォルト値が意図せずトゥイーンを上書きしていないことを確認します。
  • 速度を落として確認:gsap.globalTimeline.timeScale(0.5)。

ScrollTrigger に関する問題

  • デバッグを有効にする:markers: true(開発時のみ)。
  • 開始位置/終了位置を検証する:開始位置/終了位置がレイアウトと要素の高さに合っていることを確認します。
  • レイアウト変更後に更新する:画像/フォント/動的コンテンツの読み込みが完了した後、ScrollTrigger.refresh() を呼び出します。
  • カスタムスクローラー:window を使用しない場合は、scroller を一貫して設定します。
  • ピン留め時のジャンプ/ちらつき:anticipatePin を試し、レイアウトシフトを確認して、invalidateOnRefresh を検討します。

パフォーマンスに関する問題

  • ポインター/マウスのカクつき:イベントごとにトゥイーンを作成しないでください。quickTo/quickSetter を使用します。
  • トリガーが多すぎる:数を減らし、バッチ処理を使い、タイムラインを統合します。
  • レイアウトのスラッシングを避ける:読み取りをまとめてから書き込み、transform を優先します。
  • 負荷の高いプロパティ:可能な限り top/left/width/height を避けます。

19)「プラグインが利用できない場合」の方針

ユーザーがプラグインを使用できない場合(ポリシー/オフラインの制約):

  1. まず公式プラグインの利用方法を提示する
  2. GSAP コア + CSS/JS を使った独自の回避策を提示する
  3. 制約を明示する:エッジケース、保守性、パフォーマンス、クロスブラウザー間の同等性

クラック版/海賊版プラグインは決して提案しないでください。


20)すぐに使えるインタラクションレシピ

ホバー時のマイクロインタラクション

const el = document.querySelector(".btn");
el.addEventListener("mouseenter", () =>
  gsap.to(el, { scale: 1.03, duration: 0.2, overwrite: "auto" })
);
el.addEventListener("mouseleave", () =>
  gsap.to(el, { scale: 1.00, duration: 0.25, overwrite: "auto" })
);

カーソル追従(高パフォーマンス)

const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });

マグネティックボタン

const btn = document.querySelector(".magnetic");
const strength = 0.3;

btn.addEventListener("mousemove", (e) => {
  const rect = btn.getBoundingClientRect();
  const x = e.clientX - rect.left - rect.width / 2;
  const y = e.clientY - rect.top - rect.height / 2;
  gsap.to(btn, { x: x * strength, y: y * strength, duration: 0.3 });
});

btn.addEventListener("mouseleave", () => {
  gsap.to(btn, { x: 0, y: 0, duration: 0.5, ease: "elastic.out(1, 0.3)" });
});

スクロール時のリビール

gsap.from(".reveal", {
  y: 24, autoAlpha: 0, duration: 0.8, ease: "power3.out",
  scrollTrigger: {
    trigger: ".reveal",
    start: "top 85%",
    toggleActions: "play none none reverse"
  }
});

リスト項目を順番にリビール

gsap.from(".list-item", {
  y: 30,
  autoAlpha: 0,
  duration: 0.6,
  stagger: 0.1,
  ease: "power3.out",
  scrollTrigger: { trigger: ".list", start: "top 80%" }
});

視差効果のあるヒーロー

gsap.to(".hero-bg", {
  yPercent: 30,
  ease: "none",
  scrollTrigger: {
    trigger: ".hero",
    start: "top top",
    end: "bottom top",
    scrub: true
  }
});

このスキルに含まれるリファレンス

以下を参照してください:

  • references/GSAP_CORE.md
  • references/GSAP_RECIPES.md
  • references/UI_INTERACTIONS.md
  • references/TEXT_ANIMATIONS.md
  • references/PHYSICS_PLUGINS.md
  • references/NEXTJS_REACT_PATTERNS.md
  • references/GSDEVTOOLS.md
  • references/DEBUG_CHECKLIST.md

コメント