WichyCake
WichyCake

Reputation: 616

React Spring delay switching transitions

The title maybe not on spot, but I will try to explain here. I've been using SwitchTransition in in-out mode but since my animation was done using mostly hook useSpring from react-spring package, I would rather move from React Transition Group completely. But I am not quite sure how to achieve the same effect. When a transition happens (for routes) I need for the old component stay visible (say for 2000 milliseconds) while the new one is already visible. Looking at the hook useTransition in react-spring I don't see a way to introduce a delay for leave.

const transition = useTransition(show, null, {
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
  config: {
    duration: 200, // duration for the whole animation form start to end
  },
})

In SwitchTransition it would be something like that:

<SwitchTransition mode='in-out'>
  <CSSTransition
    key={location.pathname}
    timeout={{ enter: 2000, exit: 400 }}
    unmountOnExit
    onEnter={()=>{callback}}
  >
    /* here go routes */
  </CSSTransition>
</SwitchTransition>

How to do the same in React Spring with useTransition?

Upvotes: 2

Views: 9913

Answers (3)

Fil. V.
Fil. V.

Reputation: 19

I think I dont understand at all, but you can add delay prop and add a function instead an object like this:

 let location = useLocation();
  const transition = useTransition(location, {
      from: { opacity: 0 },
      enter: item => async (next, cancel) => {
          await next({ opacity: 1, y: 0, })
          await next({ opacity: 1, y: 70, })
        },
      leave: { opacity: 0, delay:400 },
    })

and modify a sequence suitable for you. i am completely sure you can find another info here: https://react-spring.io/hooks/use-transition

transition(
  (props, item) => {
    return (
      <a.div className='main' style={props} >
        <Switch location={item} >
          <Route path='/hours' component={HoursPage} />
          <Route path='/city' component={CityPage} />
          <Route path='/' component={InicioPage} />
        </Switch>
      </a.div>
    )
  }
)
      

Upvotes: 1

Firoj Siddiki
Firoj Siddiki

Reputation: 1941

Method 1: simplest one is, using trail property

const transition = useTransition(show, null, {
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
  trail:150
})

Method 2: For adding different delay to each item by using additional delay array

Here is the working demo for both methods: https://codesandbox.io/embed/pensive-satoshi-yi4uw?fontsize=14&hidenavigation=1&theme=dark

Hope this helps somebody

Upvotes: 5

Peter Ambruzs
Peter Ambruzs

Reputation: 8213

I do not know any separate timing for enter and leave, but you can do something similar with interpolation. For example you define x value instead of opacity.

  const transition = useTransition(show, s => (s ? "on" : "off"), {
    from: { x: 0 },
    enter: { x: 1 },
    leave: { x: 2 },
    config: {
      duration: 4000 // duration for the whole animation form start to end
    }
  });

In the render method you can interpolate the opacity from x:

    {transition.map(({ item, props, key }) => (
      <animated.div
        key={key}
        style={{
          opacity: props.x.interpolate({
            range: [0.0, 1, 1.25, 2],
            output: [0, 1, 0, 0]
          })
        }}
      >
        {item ? "on" : "off"}
      </animated.div>
    ))}

So what is going here? Duration is 4 sec. When entering x goes from 0 to 1 it interpolates as opacity also 0 to 1 for the whole 4 sec. When leaving x goes 1 to 2. It interpolates first 1 to 1.25 as opacity 1 to 0 then the opacity remains 0 to the rest of the animation. So leaving animation opacity change from 1 to 0 will happen approximately in 1 sec.

What do you think about it?

Here is an example: https://codesandbox.io/s/zen-curran-nnuiu

Upvotes: 0

Related Questions