You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中onMouseLeave事件调用gsap.reverse()不生效问题咨询

React中GSAP hover动画reverse无效问题解决

问题根因

你当前的代码每次调用hoverScaleAnimation函数都会创建一个全新的GSAP动画实例,onLeave事件中调用reverse()的是新生成的实例,并非onEnter时已经开始播放的那个动画,因此反向播放没有效果。同时多次调用gsap.to会给同一元素叠加多段动画,也可能导致状态冲突。

解决方案

你需要复用同一个动画实例,不要每次事件触发都重新创建动画,用useRef存储初始化好的动画实例即可,实现步骤如下:

  1. 声明两个ref,分别存储目标DOM元素、GSAP动画实例
  2. 组件挂载时仅初始化一次动画,设置paused: true默认暂停
  3. 鼠标进出事件直接操作已有的动画实例,调用play()/reverse()

代码示例

import { useRef, useLayoutEffect } from 'react'
import gsap from 'gsap'

const YourComponent = () => {
  // 存储目标DOM元素
  const itemRef = useRef<HTMLDivElement>(null)
  // 存储唯一的GSAP动画实例
  const hoverAnimRef = useRef<gsap.core.Tween | null>(null)

  // 组件挂载时初始化动画,仅执行一次
  useLayoutEffect(() => {
    if (!itemRef.current) return
    hoverAnimRef.current = gsap.to(itemRef.current, {
      scale: 1.05,
      paused: true // 初始化后默认暂停,等待事件触发播放
    })
  }, [])

  const onEnter = () => {
    hoverAnimRef.current?.play()
  }

  const onLeave = () => {
    hoverAnimRef.current?.reverse()
  }

  return <div ref={itemRef} onMouseEnter={onEnter} onMouseLeave={onLeave}>hover 测试元素</div>
}

可选:封装为公共Hook

如果需要多个组件复用这个hover缩放逻辑,可以封装为自定义Hook:

const useHoverScaleAnim = <T extends HTMLElement>() => {
  const targetRef = useRef<T>(null)
  const animRef = useRef<gsap.core.Tween | null>(null)

  useLayoutEffect(() => {
    if (!targetRef.current) return
    animRef.current = gsap.to(targetRef.current, {
      scale: 1.05,
      paused: true
    })
  }, [])

  const handlers = {
    onMouseEnter: () => animRef.current?.play(),
    onMouseLeave: () => animRef.current?.reverse()
  }

  return [targetRef, handlers] as const
}

// 组件内使用
const Item = () => {
  const [itemRef, hoverHandlers] = useHoverScaleAnim<HTMLDivElement>()
  return <div ref={itemRef} {...hoverHandlers}>item内容</div>
}

注意事项

如果是循环渲染的多个需要hover动画的元素,需要给每个元素单独声明对应的DOM ref和动画实例ref,不要共用同一个ref,避免多个元素动画互相干扰。

内容的提问来源于stack exchange,提问作者crevulus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 19:36:03