gsap-interact

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GSAP Interact — Mouse-Driven Animations

GSAP Interact — 鼠标驱动动画

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).

流程: gsap-setup → gsap-animate → gsap-interact → gsap-optimise → gsap-test
配套技能: 如需GSAP核心补间API,请调用gsap-core。如需性能优化方法,请调用gsap-performance。本技能仅涵盖交互实现方案。依赖:
greensock/gsap-skills
所有实现模式均假设已配置
gsap.context()
清理机制(详见gsap-animate技能)。

1. 3D Tilt Cards

1. 3D倾斜卡片

Cursor-to-rotation calculation

光标到旋转角度的计算

js
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
js
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

结合ctx.add的完整配置

js
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; }

js
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)
所需CSS:
.tilt-wrapper { perspective: 1000px; }
.tilt-shell { transform-style: preserve-3d; }

2. Patterns & Best Practices

2. 实现模式与最佳实践

js
// 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.
js
// 1. 所有事件处理函数中的补间动画都要通过ctx.add注册以实现清理
self.add('onHover', (el) => { gsap.to(el, { scale: 1.05, overwrite: 'auto' }) })

// 2. 所有高频触发的补间动画都要设置overwrite: 'auto'
gsap.to(el, { x: 100, overwrite: 'auto' })

// 3. 在动画开始时设置will-change,在动画完成时释放
el.style.willChange = 'transform'
gsap.to(el, { x: 0, onComplete: () => { el.style.willChange = 'auto' } })

// 4. 对反复执行动画的元素设置force3D: true
gsap.set(el, { force3D: true })
请查看gsap-performance技能获取工具选择指南。

Cleanup checklist

清理检查清单

  1. Every interactive tween registered via
    ctx.add('name', fn)
  2. ctx.revert()
    called in
    onUnmounted
  3. transformPerspective
    set via
    gsap.set
    (not per-frame)
  4. quickTo
    instances created in
    onMounted
    , not in handlers
  5. will-change
    released in
    onComplete
    , never permanent

  1. 每个交互式补间动画都通过
    ctx.add('name', fn)
    注册
  2. onUnmounted
    中调用
    ctx.revert()
  3. 通过
    gsap.set
    设置
    transformPerspective
    (而非逐帧设置)
  4. onMounted
    中创建
    quickTo
    实例,而非在事件处理函数中
  5. onComplete
    中释放
    will-change
    ,切勿永久设置

References

参考资料

  • references/interaction-patterns.md
    — Draggable with liveSnap for SVG point editing, macOS Dock magnification effect
  • references/interaction-patterns.md
    — 结合liveSnap的Draggable实现SVG点编辑、macOS停靠栏放大效果