gsap-cursor について
gsap-cursorは、GSAPでポインター連動エフェクトを作る開発者向けのスキルです。磁石のように動くボタンから画像プレビュー、遠近傾斜までのアニメーション例とクリーンアップ方法を扱います。
主な機能
- 01quickToによるボタンの磁石状移動
- 02距離に応じたパーティクルトレイル
- 03バネのように追従する要素
- 04クリップパスによるスポットライト
- 05ポインター追従画像プレビュー
- 06ポインター駆動の遠近傾斜
活用シーン
- 01ボタンに磁石状の動きを追加
- 02ポインターに続く粒子軌跡の作成
- 03移動するスポットライトでコンテンツを表示
- 04リスト項目のホバー時に画像を表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iotron/ gsap-cookbook --skill gsap-cursorインストール後、Claude Code で/gsap-cursorを入力して読み込まれたか確認します。
同梱ファイルreferences/cursor-patterns.md
詳細
GSAP Cursor — ポインター駆動エフェクト
フロー:gsap-setup → gsap-animate → gsap-cursor → gsap-optimise → gsap-test
関連スキル:GSAP コアのトゥイーン API については、gsap-core を呼び出してください。パフォーマンス関連のメソッドについては、gsap-performance を呼び出してください。このスキルではカーソルエフェクトのレシピのみを扱います。必要なもの:
greensock/gsap-skills
すべてのパターンで、gsap.context() によるクリーンアップが設定済みであることを前提としています(gsap-animate スキルを参照してください)。
1. マグネティックボタン(quickTo)
gsap.quickTo はトゥイーンを事前コンパイルするため、頻繁に更新する場合は gsap.to よりも 50〜250%高速です。
let xTo, yTo
ctx = gsap.context(() => {
xTo = gsap.quickTo(btn, 'x', { duration: 0.4, ease: 'power3' })
yTo = gsap.quickTo(btn, 'y', { duration: 0.4, ease: 'power3' })
}, scopeRef.value)
function onMagnetMove(e) {
const rect = btn.getBoundingClientRect()
xTo((e.clientX - rect.left - rect.width / 2) * 0.35)
yTo((e.clientY - rect.top - rect.height / 2) * 0.35)
}
function onMagnetLeave() { xTo(0); yTo(0) }
quickTo と quickSetter の API 比較については、gsap-performance スキルを参照してください。
2. Flair パーティクルトレイル
gsap.ticker とプールの再利用を使って、距離に応じてパーティクルを生成します。要素はカーソル位置に再び現れ、アニメーション後、gsap.utils.wrap を使って再利用されます。
コアループ(gsap.ticker.add を通じて各ティックで実行):
gsap.ticker.add(() => {
const dist = Math.hypot(lastPos.x - mousePos.x, lastPos.y - mousePos.y)
if (dist > gap) { spawnParticle(); lastPos = mousePos }
})
生成:gsap.set で要素をカーソル位置に配置し、gsap.utils.wrap(0, pool.length) でインデックスを循環させます。タイムラインでパーティクルを拡大し、フェードさせて落下させます。
プールの設定とアニメーションタイムラインを含む完全な実装は、
references/cursor-patterns.mdを参照してください。
3. スプリング物理のエラスティックフォロワー
複数のブロブが異なる duration 値でカーソルを追いかけることで、時間差のある物理的な動きを表現します。各ブロブでは elastic.out イージングと overwrite: 'auto' を使用します。
self.add('moveBlobs', (mx, my) => {
blobs.forEach((blob, i) => {
gsap.to(blob.el, {
x: mx, y: my,
duration: blob.dur, ease: 'elastic.out(1.2, 0.3)',
overwrite: 'auto', force3D: true,
})
})
})
静止位置はパーセンテージ基準(containerWidth * pct / 100)で、リセット時に再計算されます。
ブロブの設定、セットアップ、リセットを含む完全な実装は、
references/cursor-patterns.mdを参照してください。
4. スポットライトカーソル(Clip-Path の円)
clipPath の円をカーソルに追従するようにアニメーションさせ、隠れたレイヤーを表示します。
self.add('moveSpotlight', (x, y) => {
gsap.to(spotlight, {
clipPath: `circle(130px at ${x}px ${y}px)`,
duration: 0.25, ease: 'power2.out', overwrite: 'auto',
})
})
初期状態:クリーンに元に戻せるよう、gsap.set(spotlight, { clipPath: 'circle(0px at 50% 50%)' }) を設定します。
非表示アニメーションを含む完全な実装は、
references/cursor-patterns.mdを参照してください。
5. カーソル追従型の画像プレビュー
リスト項目にマウスを乗せると、画像がカーソルに追従します。最初に入ったときの補間遅延を避けるため、2 つの引数によるスナップを使った gsap.quickTo を使用します。
const setX = gsap.quickTo(image, "x", { duration: 0.4, ease: "power3" })
// On first enter, snap: setX(e.clientX, e.clientX)
// On subsequent moves: setX(e.clientX)
一時停止した autoAlpha トゥイーンは、mouseenter/mouseleave 時に play()/reverse() を使って表示を切り替えます。
完全な実装は、
references/cursor-patterns.mdを参照してください。
6. カーソル駆動のパースペクティブ傾斜
ポインターの位置に応じて、3D パースペクティブの傾斜を制御します。親要素には perspective: 650 を設定し、子要素は gsap.quickTo と gsap.utils.interpolate を使って回転・移動します。
gsap.set("main", { perspective: 650 })
const outerRX = gsap.quickTo(".card", "rotationX", { ease: "power3" })
// pointermove: outerRX(gsap.utils.interpolate(15, -15, e.y / innerHeight))
// pointerleave: outerRX(0)
奥行きの視差を表現するため、外側の要素を回転(rotationX/Y)させ、内側の要素を移動(x/y)させます。
完全な実装は、
references/cursor-patterns.mdを参照してください。
7. ベストプラクティス
// 1. overwrite: 'auto' on EVERY rapid-fire tween — prevents pile-up
gsap.to(el, { x: 100, overwrite: 'auto' })
// 2. ctx.add for cleanup — all event-handler tweens registered via ctx.add
self.add('onMove', (x, y) => { gsap.to(el, { x, y, overwrite: 'auto' }) })
// 3. will-change lifecycle — set on start, release onComplete
el.style.willChange = 'transform'
gsap.to(el, { x: 0, onComplete: () => { el.style.willChange = 'auto' } })
// 4. force3D: true on repeatedly animated elements
gsap.set(el, { force3D: true })
// 5. quickTo in onMounted, not in handlers — create once, call many
クリーンアップのチェックリスト
- カーソルの各トゥイーンは
ctx.add('name', fn)を通じて登録する onUnmountedでctx.revert()を呼び出すquickToのインスタンスはハンドラー内ではなく、onMountedで作成するwill-changeはonCompleteで解除し、設定したままにしない- ティッカーを使うエフェクトでは、クリーンアップ時に
gsap.ticker.remove(fn)を呼び出す
参考資料
references/cursor-patterns.md— Flair パーティクルトレイル、スプリング物理フォロワー、スポットライトカーソル、回路のグロー、カーソル追従型の画像プレビュー、カーソル駆動のパースペクティブ傾斜