react-spring 动画仅适用于点击,不适用于悬停

react-spring animation only working on click, not on hover

我有一个基本的旋转立方体,我用 react-three-fiber 做了,onPointerOver(也试过 onPointerEnter)我想通过 [= 将它平滑地旋转到它的起始位置14=]。但是,当我悬停时它不仅不这样做,而且只会这样做onClick。我有一个完全不同的函数来执行 onClick——如果我禁用了那个道具,那么旋转重置就会完全失败。

我的 Box 组件中的设置非常简单:

export const Box = () => {
  const [active, setActive] = useState(false);
  const boxRef = useRef<Mesh>();

  const starterRotation = [0, 1, 1];

  useFrame(() => {
    if (boxRef.current) {
      boxRef.current.rotation.x += 0.01;
      boxRef.current.rotation.y -= 0.01;
    }
  });

  const [resetRotation, setSpring] = useSpring(() => ({
    rotation: starterRotation
  })); // trying to use the `set` syntax to call the useSpring and smoothly animate to a certain rotation.
  const springs = useSpring({ scale: active ? 1.5 : 1, config: config.wobbly });

  return (
    <animated.mesh
      // @ts-ignore
      rotation={resetRotation.rotation}
      scale={springs.scale}
      onClick={() => setActive(!active)}
      onPointerOver={() => setSpring.start()}
      ref={boxRef}
    >
      <boxGeometry args={[2, 1, 2]} />
      <meshStandardMaterial color="royalblue" />
    </animated.mesh>
  );
};

这是一个活生生的例子:https://codesandbox.io/s/react-spring-rotating-cube-np4v6

从他们的 docs 我可以看出这是正确的方法。我还看到了一些关于它的 github 问题讨论,似乎有人担心 useSpring 解构的第二个参数不能正常工作,但轮换对我有用——它只是触发事件那行不通的。

它确实有效,问题是您仍在根据 useFrame 调用中的引用更新 rotation,因此每帧都会更新。这将覆盖动画值。

第二个问题是,如果您阻止 useFramerotation 设置动画,它将无法工作,因为 spring 的内部值将设置为 [0,1,1] 但这就是您希望它动画化的内容。

这是一个使用 fromto 属性 useSpring 的好机会,我会做的是使用 ref 停止 useFrame 动画然后使用 ref 获取旋转的当前值以用作 springSet.start 函数中的 from 然后 to 这是您声明的 starterRotation 值。

你可以在这里看到这个效果 – https://codesandbox.io/s/react-spring-rotating-cube-forked-1j02g?file=/src/components/Box.tsx