javascriptreactjsanimationreact-spring

How do I make a react-spring trigger a different spring in another element?


According to the react-spring documentation, their "imperative API" provides methods for stopping and starting springs using start and stop methods, respectively. Thus, it should be possible to write two springs, the first triggering the second:

  const [blueSpring, blueSpringAPI] = useSpring(
    () => ({
      from: { x: 0 },
      to: { x: 100 },
      config: { duration: 3000 },
      onRest: () => {
        pinkSpringAPI.start();
      },
    }),
    []
  );

  const [pinkSpring, pinkSpringAPI] = useSpring(
    () => ({
      from: { y: 100 },
      to: { y: 200 },
      config: { duration: 3000 },
    }),
    []
  );

  pinkSpringAPI.stop();

Of course, stopping the second spring so we can tell when the first one triggers it.

However, this code does NOT work as expected. The springs run simultaneously. Am I doing something wrong with my usage of the springref API?

codesandbox: https://codesandbox.io/p/sandbox/dpv9yf


Solution

  • What seems to work is not initially animating the pink spring to a to position, and then at the resting phase of the blue spring start a new pink spring animation to a new position.

    Example:

    const [blueSpring, blueSpringAPI] = useSpring(
      () => ({
        from: { x: 0 },
        to: { x: 100 },
        config: { duration: 3000 },
        onRest: () => {
          pinkSpringAPI.start({
            // current `from` to next `to` and `duration`
            to: { y: 200 },
            config: { duration: 3000 },
          });
        },
      }),
      []
    );
    
    const [pinkSpring, pinkSpringAPI] = useSpring(
      () => ({
        from: { y: 100 },
        // no `to` position, no `duration`
      }),
      []
    );