nandorojo / moti

🐼 The React Native (+ Web) animation library, powered by Reanimated 3.
https://moti.fyi
MIT License
3.9k stars 120 forks source link

question about multi transtion #288

Closed fukemy closed 1 year ago

fukemy commented 1 year ago

Is there an existing issue for this?

Current Behavior

assume I have animation like this:

animate={{ transform: [{scale: [0, 1.6, 1]}, { translateY: [ 0, -50, 0]}] }}

I want to timing for scale[0,1.6] + translateY[0, -50] Then spring for scale[1.6, 1] + translate[-50, 0]

Can you help me how to do this

Expected Behavior

No response

Steps To Reproduce

No response

Versions

- Moti:lasted
- Reanimated:2.10.0
- React Native: 0.68.2

Screenshots

No response

Reproduction

No snack here

fukemy commented 1 year ago

I tried to using below method but not working:

<MotiView
        from={{ transform: [{scale: [0, 1.6]}, { translateY: [0, -50]}] }}
        animate={{ transform: [{scale: [1.6, 1]}, { translateY: [-50, 0]}] }}
        transition={{
            // type: 'spring',
            duration: 500,
            from: {
                type: 'timing'
            },
            animate:{
                type: 'spring'
            }
        }}   
nandorojo commented 1 year ago

I recommend reading all the usage docs, where the many transition options are available.

from and animate are not valid keys. However, you have many options.

First off, I wouldn't use a sequence array in from. from is intended to just be the initial state of the component. There's no need to use from in your case.

Second, the sequence transitions allow granular transitions on a per-item basis:

Screenshot 2023-06-25 at 4 51 32 PM

Rather than using transform, I recommend flattening your transform values, as documented on the transforms page.

import { TransitionConfigWithoutRepeats, MotiView } from 'moti'

const spring: TransitionConfigWithoutRepeats = {
  type: 'spring',
  // ...other config
}

const timing: TransitionConfigWithoutRepeats = {
  type: 'timing',
  duration: 500
}

// in your component:
<MotiView
  animate={{
    scale: [
      { value: 0, ...timing },
      { value: 1.6, ...timing },
      { value: 1.6, ...spring }, // you might be able to delete this
      { value: 1, ...spring },
    ],
    translateY: [
      { value: 0, ...timing },
      { value: -50, ...timing },
      { value: -50, ...spring }, // you might be able to delete this
      { value: 0, ...spring },
    ],
  }}
/>

Alternatively, you could put the transitions inline:

<MotiView
  animate={{
    scale: [
      0,
      1.6,
      { value: 1.6, type: 'spring' }, // you might be able to delete this
      { value: 1, type: 'spring' },
    ],
    translateY: [
       0,
       - 50,
      { value: -50, type: 'spring' }, // you might be able to delete this
      { value: 0, type: 'spring' },
    ],
  }}
  transition={{
    // default value for all animations
    type: 'timing',
    duration: 500
  }}
/>

Lastly, consider memoizing it:

const sequenceComponent = useMemo(
  () => (
    <MotiView
      animate={{
        scale: [
          0,
          1.6,
          { value: 1.6, type: "spring" }, // you might be able to delete this
          { value: 1, type: "spring" },
        ],
        translateY: [
          0,
        - 50,
          { value: -50, type: "spring" }, // you might be able to delete this
          { value: 0, type: "spring" },
        ],
      }}
      transition={{
        // default value for all animations
        type: "timing",
        duration: 500,
      }}
    />
  ),
  []
);

return <>{sequenceComponent}</>