Home > front end >  react-spring animation only working on click, not on hover
react-spring animation only working on click, not on hover

Time:12-08

I have a basic rotating cube I've made with react-three-fiber, and onPointerOver (also tried onPointerEnter) I want to smoothly rotate it to its starting position via useSpring. However, not only does it not do so when I hover, but it will only do so onClick. I have a totally different function that executes onClick -- and if I disabled that prop then the rotation reset fails altogether.

I've got a pretty simple set up in my Box component:

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

Here's a live example: https://codesandbox.io/s/react-spring-rotating-cube-np4v6

From what I can tell in their docs this is the correct way. I also saw some github issues discussions on it, and there seemed to be some concern about the second argument of the useSpring deconstruction not working properly, but the rotation works for me -- it's jut the triggering event that won't work.

CodePudding user response:

It does work, the issue is you're still updating the rotation based on the ref in a useFrame call so that's updated every frame. Which will override the animation value.

The second issue is that if you stoped the useFrame from animating rotation it won't work because the spring's internal value will be set to [0,1,1] but that's what you want it to animate to.

This is a good opportunity to use from and to props of useSpring, what I would do is use a ref to stop the useFrame animation and then use the ref to get the current values of the rotation to use as from in the springSet.start function and then to which is the starterRotation value you've declared.

You can see this in effect here – https://codesandbox.io/s/react-spring-rotating-cube-forked-1j02g?file=/src/components/Box.tsx

  • Related