GSAP Interact — Mouse-Driven Animations
Flow: gsap-setup → gsap-animate → gsap-interact → gsap-optimise → gsap-test
Companion: For GSAP core tween API, invoke gsap-core. For performance methods, invoke gsap-performance. This skill covers interaction recipes only. Requires: greensock/gsap-skills
All patterns assume gsap.context() cleanup is in place (see gsap-animate skill).
1. 3D Tilt Cards
Cursor-to-rotation calculation
const rect = card.getBoundingClientRect()
const xPct = ((e.clientX - rect.left) / rect.width - 0.5) * 2
const yPct = ((e.clientY - rect.top) / rect.height - 0.5) * 2
Full setup with ctx.add
const TILT_IN = { duration: 0.35, ease: 'power2.out', overwrite: 'auto' }
const TILT_OUT = { duration: 0.7, ease: 'elastic.out(1, 0.4)', overwrite: 'auto' }
ctx = gsap.context((self) => {
gsap.set(card, { transformPerspective: 900, force3D: true })
self.add('applyTilt', (xPct, yPct) => {
card.style.willChange = 'transform'
gsap.to(card, { rotationY: xPct * 14, rotationX: -yPct * 14, ...TILT_IN })
gsap.to(inner, { x: xPct * 10, y: yPct * 10, force3D: true, ...TILT_IN })
})
self.add('resetTilt', () => {
gsap.to(card, { rotationX: 0, rotationY: 0, ...TILT_OUT,
onComplete: () => { card.style.willChange = 'auto' } })
gsap.to(inner, { x: 0, y: 0, force3D: true, ...TILT_OUT })
})
}, scopeRef.value)
Required CSS: .tilt-wrapper { perspective: 1000px; } .tilt-shell { transform-style: preserve-3d; }
2. Patterns & Best Practices
// 1. ALL event-handler tweens inside ctx.add for cleanup
self.add('onHover', (el) => { gsap.to(el, { scale: 1.05, overwrite: 'auto' }) })
// 2. overwrite: 'auto' on EVERY rapid-fire tween
gsap.to(el, { x: 100, overwrite: 'auto' })
// 3. will-change: 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 })
See gsap-performance skill for tool selection guidance.
Cleanup checklist
- Every interactive tween registered via
ctx.add('name', fn)
ctx.revert() called in onUnmounted
transformPerspective set via gsap.set (not per-frame)
quickTo instances created in onMounted, not in handlers
will-change released in onComplete, never permanent
References
references/interaction-patterns.md — Draggable with liveSnap for SVG point editing, macOS Dock magnification effect
1---2name: gsap-interact3description: Production recipes for mouse-driven interactive GSAP animations. Companion to official gsap-core and gsap-performance skills (API reference). Triggers: GSAP mouse, mousemove animation, tilt card, 3D tilt, quickTo, quickSetter, hover animation, interactive GSAP, parallax hover, drag interaction, Draggable, liveSnap, mouse-driven animation, dock effect, macOS dock, magnification, proximity scale, dock magnify. Non-triggers: Not for scroll-driven animation (use gsap-scroll), text effects (use gsap-text), SVG drawing (use gsap-svg), visual effects like glitch/marquee (use gsap-vfx), or cursor/pointer effects (use gsap-cursor). Outcome: Produces mouse-driven interactive animations — tilt cards, hover effects, and drag interactions.4---56# GSAP Interact — Mouse-Driven Animations78> **Flow**: gsap-setup → gsap-animate → **gsap-interact** → gsap-optimise → gsap-test910> **Companion**: For GSAP core tween API, invoke **gsap-core**. For performance methods, invoke **gsap-performance**. This skill covers interaction recipes only. Requires: `greensock/gsap-skills`1112All patterns assume `gsap.context()` cleanup is in place (see gsap-animate skill).1314---1516## 1. 3D Tilt Cards1718### Cursor-to-rotation calculation1920```js21const rect = card.getBoundingClientRect()22const xPct = ((e.clientX - rect.left) / rect.width - 0.5) * 223const yPct = ((e.clientY - rect.top) / rect.height - 0.5) * 224```2526### Full setup with ctx.add2728```js29const TILT_IN = { duration: 0.35, ease: 'power2.out', overwrite: 'auto' }30const TILT_OUT = { duration: 0.7, ease: 'elastic.out(1, 0.4)', overwrite: 'auto' }3132ctx = gsap.context((self) => {33 gsap.set(card, { transformPerspective: 900, force3D: true })3435 self.add('applyTilt', (xPct, yPct) => {36 card.style.willChange = 'transform'37 gsap.to(card, { rotationY: xPct * 14, rotationX: -yPct * 14, ...TILT_IN })38 gsap.to(inner, { x: xPct * 10, y: yPct * 10, force3D: true, ...TILT_IN })39 })4041 self.add('resetTilt', () => {42 gsap.to(card, { rotationX: 0, rotationY: 0, ...TILT_OUT,43 onComplete: () => { card.style.willChange = 'auto' } })44 gsap.to(inner, { x: 0, y: 0, force3D: true, ...TILT_OUT })45 })46}, scopeRef.value)47```4849**Required CSS**: `.tilt-wrapper { perspective: 1000px; }` `.tilt-shell { transform-style: preserve-3d; }`5051---5253## 2. Patterns & Best Practices5455```js56// 1. ALL event-handler tweens inside ctx.add for cleanup57self.add('onHover', (el) => { gsap.to(el, { scale: 1.05, overwrite: 'auto' }) })5859// 2. overwrite: 'auto' on EVERY rapid-fire tween60gsap.to(el, { x: 100, overwrite: 'auto' })6162// 3. will-change: set on start, release onComplete63el.style.willChange = 'transform'64gsap.to(el, { x: 0, onComplete: () => { el.style.willChange = 'auto' } })6566// 4. force3D: true on repeatedly animated elements67gsap.set(el, { force3D: true })68```6970> See **gsap-performance** skill for tool selection guidance.7172### Cleanup checklist73741. Every interactive tween registered via `ctx.add('name', fn)`752. `ctx.revert()` called in `onUnmounted`763. `transformPerspective` set via `gsap.set` (not per-frame)774. `quickTo` instances created in `onMounted`, not in handlers785. `will-change` released in `onComplete`, never permanent7980---8182## References8384- `references/interaction-patterns.md` — Draggable with liveSnap for SVG point editing, macOS Dock magnification effect