Search code examples
javascriptreactjsanimationreact-spring

React spring transition, achieve a progressive delay in the entry of each element


The first example shown on the react-spring transition page is wrong, the code does not correspond to the animation shown.

How could I achieve that same effect?, how can I get a delay between the input of each component and using spring easing?.

When I try this, all components are entered at the same time.

Use transition example


Solution

  • These examples in the documentation are just drafts to give you some overview. It is a shame that react-spring only provides more advanced animations and lacks some basic example.

    Anyway. The most basic delay between elements can be achieved with the trail property of the transition.

      const transitions = useTransition(items, item => item, {
        from: { transform: "translate3d(0,-40px,0)", display: "inline-block" },
        enter: { transform: "translate3d(0,0px,0)" },
        leave: { transform: "translate3d(0,-40px,0)" },
        trail: 100
      });
    

    You can use this parameter only for sequential delay. When more than one item added or removed from the array your transition based on.

    https://codesandbox.io/s/new-bird-sztw9

    In the first example they do not use this. They are supposed to add and remove the item to the list a little staggered. I try to reproduce it. This is the staggered add:

      function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
      }
    
      const handleClick = async () => {
        if (items.length === 0) {
          set([3]);
          await sleep(1000);
          set([2, 3]);
          await sleep(1000);
          set([2, 3, 4]);
          await sleep(1000);
          set([1, 2, 3, 4]);
        } ...
    

    https://codesandbox.io/s/shy-sky-56lrw

    This is closer to the example. But there are slight bumps when the mounts/unmounts of the transitions happen.

    I hope it helps.

    As a side note. I checked the source code of the react-spring page and they are cheating. The first example is do not even use transitions for the smooth animation. It uses interpolate to orchestrate the movement of each number. This is some advanced use with special components.

          <RewindSpring>
            {x => (
              <>
                <animated.div
                  style={{
                    opacity: x.interpolate({range: [0.75, 1.0], output: [0, 1]}),
                    transform: x.interpolate({range: [0.75, 1.0], output: [-40, 0], extrapolate: 'clamp'}).interpolate(x => `translate3d(0,${x}px,0)`)
                  }}
                >
                  1
                </animated.div>
                <animated.div
                  style={{
                    opacity: x.interpolate({range: [0.25, 0.5], output: [0, 1]}),
                    transform: x.interpolate({range: [0.25, 0.5], output: [-40, 0], extrapolate: 'clamp'}).interpolate(x => `translate3d(0,${x}px,0)`)
                  }}
                >
                  2
                </animated.div>
                <animated.div
                  style={{
                    opacity: x.interpolate({range: [0.0, 0.25], output: [0, 1]}),
                    transform: x.interpolate({range: [0.0, 0.25], output: [-40, 0], extrapolate: 'clamp'}).interpolate(x => `translate3d(0,${x}px,0)`)
                  }}
                >
                  3
                </animated.div>
                <animated.div
                  style={{
                    opacity: x.interpolate({range: [0.5, 0.75], output: [0, 1]}),
                    transform: x.interpolate({range: [0.5, 0.75], output: [-40, 0], extrapolate: 'clamp'}).interpolate(x => `translate3d(0,${x}px,0)`)
                  }}
                >
                  4
                </animated.div>
              </>
            )}
          </RewindSpring>