gsap-master について
インタラクティブな UI に GSAP v3 のアニメーションを実装するためのスキルです。タイムライン設計、スクロールやジェスチャー、テキストと SVG の演出に加え、パフォーマンス、アクセシビリティ、フレームワークでのクリーンアップを扱います。
主な機能
- 01Tween と Timeline の構成
- 02スクロール連動アニメーション
- 03ドラッグとジェスチャー操作
- 04テキストと SVG のアニメーション
- 05性能と動きを減らす設定への配慮
活用シーン
- 01スクロール連動のページ演出
- 02ドラッグ式カルーセルやスライダーの作成
- 03段階的なテキスト表示の追加
- 04React や Next.js でのアニメーション整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ su69ar/ rdnax-gsap-master --skill gsap-masterインストール後、Claude Code で/gsap-masterを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/DEBUG_CHECKLIST.mdGSAP_CORE.mdGSAP_RECIPES.mdGSDEVTOOLS.mdNEXTJS_REACT_PATTERNS.mdPHYSICS_PLUGINS.mdTEXT_ANIMATIONS.mdUI_INTERACTIONS.mdscripts/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) 出力仕様(提供する内容)
アニメーションの実装を求められたときは、次の内容を出力します。
- モーションプラン(目標、トリガー、状態、時間、イージング)
- 実装(まず最小限の動作するコード)
- アーキテクチャ(タイムラインマップ、ラベル、再利用可能な関数/モジュール)
- レスポンシブ対応とアクセシビリティ(matchMedia と動きを抑える場合の代替)
- パフォーマンスに関する注意点(quickTo/quickSetter、レイアウトの頻繁な再計算を回避、バッチ処理)
- デバッグチェックリスト(マーカー/更新/クリーンアップ/重複)
まずは「優れた MVP」を提示し、その後に拡張を加えてください。
3) プラグイン対応マップ(完全版)
スクロールプラグイン
| プラグイン | 説明 | 使用例 |
|---|---|---|
| ScrollTrigger | スクロールに応じてアニメーションをトリガー/スクラブ/ピン留め/スナップします | ほとんどのスクロールアニメーション |
| ScrollTo | プログラムによるスムーズスクロール | ナビゲーション、CTA ボタン |
| ScrollSmoother | ネイティブベースのスムーズスクロールと視差効果 | 非常に滑らかなスクロール感 |
| Observer | ホイール/タッチ/ポインタージェスチャーを統一的に検出します | スクロールジャック、スワイプジェスチャー |
UI/インタラクション
| プラグイン | 説明 | 使用例 |
|---|---|---|
| Flip | FLIP ベースのレイアウト遷移 | グリッドの並べ替え、モーダルの拡大、共有要素 |
| Draggable | ドラッグ操作 | カルーセル、スライダー、カード |
| InertiaPlugin | 慣性/速度による滑走 | ドラッグ後の投げ出し物理効果 |
テキスト
| プラグイン | 説明 | 使用例 |
|---|---|---|
| SplitText | アニメーション用に文字/単語/行に分割します | テキストを段階的に表示 |
| ScrambleText | ランダム化されたテキストのデコード効果 | テクノロジー感のある見出し |
| TextPlugin | テキスト内容の入力/置換 | カウンター、動的ラベル |
SVG
| プラグイン | 説明 | 使用例 |
|---|---|---|
| DrawSVG | 線の描画をアニメーション化します | 線画、署名 |
| MorphSVG | SVG パス間でモーフィングします | 図形の遷移 |
| MotionPath | SVG パスに沿ってアニメーション化します | 曲線に沿った移動 |
| MotionPathHelper | パスを視覚的に編集するツール(開発ツール) | 開発ワークフロー |
物理演算/イージング/ツール
| プラグイン | 説明 | 使用例 |
|---|---|---|
| Physics2D | 2D物理演算シミュレーション | 放物運動、パーティクル |
| PhysicsProps | 任意のプロパティに物理演算を適用 | 自然なプロパティアニメーション |
| CustomEase | カスタムイージング曲線を定義 | 独自のモーション表現 |
| CustomWiggle | 振動/揺れのイージング | シェイク、振動エフェクト |
| CustomBounce | カスタムバウンスイージング | リアルなバウンド |
| EasePack | 追加の組み込みイージング | 拡張イージングライブラリ |
| GSDevTools | ビジュアルタイムラインデバッグUI | 開発ワークフロー |
レンダリングライブラリ
| プラグイン | 説明 | 使用例 |
|---|---|---|
| PixiPlugin | Pixi.jsオブジェクトをアニメーション化 | Canvas/WebGLレンダリング |
| EaselPlugin | EaselJSオブジェクトをアニメーション化 | 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)「プラグインが利用できない場合」の方針
ユーザーがプラグインを使用できない場合(ポリシー/オフラインの制約):
- まず公式プラグインの利用方法を提示する
- GSAP コア + CSS/JS を使った独自の回避策を提示する
- 制約を明示する:エッジケース、保守性、パフォーマンス、クロスブラウザー間の同等性
クラック版/海賊版プラグインは決して提案しないでください。
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