nandorojo / moti

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

Transition of "type: decay" appears to be broken #321

Open xzilja opened 8 months ago

xzilja commented 8 months ago

Is there an existing issue for this?

Do you want this issue prioritized?

Current Behavior

React native reanimated library exposes withDecay helper documented here https://docs.swmansion.com/react-native-reanimated/docs/animations/withDecay it appears from the source that moti also supports this by setting transition to type: 'decay' however, doing so breaks the app. with following error:

Unhandled Runtime Error
TypeError: animation.callback is not a function

Expected Behavior

Should not break and allow to use decay animations.

Steps To Reproduce

  1. Visit hello world example at https://moti.fyi/hello-world
  2. Change transition type from timing to decay in the example and save
  3. Test with other values like timing and spring, seems to work ok

Versions

- Moti: 0.27.0
- Reanimated: 3.5.4
- React Native: 0.72.6

Screenshots

https://github.com/nandorojo/moti/assets/3154053/8ec72422-fe31-4fea-88d3-04df5114d13c

Reproduction

https://stackblitz.com/edit/nextjs-9sshqj?file=pages%2Findex.tsx

xzilja commented 8 months ago

Related discussions that can be closed if this is an actual bug in favor of this issue.

https://github.com/nandorojo/moti/discussions/319 https://github.com/nandorojo/moti/discussions/313

nandorojo commented 8 months ago

Is it web only? Can you confirm it works with normal reanimated but just not moti?

xzilja commented 8 months ago

Bug initially popped up for me on ios, validated it with web playground. I'll whip up a test with vanilla reanimated in a moment to confirm 👍

nandorojo commented 8 months ago

Cool thanks

xzilja commented 8 months ago

Alright, reproduction for this actually needs to be hooked to gesture (that's how withDecay) works essentially. With reanimated, this behaves as expected

const pan = Gesture.Pan()
    .onChange(({ translationY }) => {
        translate.value = translationY;
    })
    .onFinalize(({ velocityY }) => {
        translate.value = withDecay({
           velocity: velocityY
        });
    })

But this (what I believe is equivalent with moti) throws an error when it hits animation with decay

const pan = Gesture.Pan()
    .onChange(({ translationY }) => {
      animationState.animateTo({ translateY: translationY, transition: { type: 'no-animation' } })
    })
    .onFinalize(({ velocityY }) => {
      animationState.animateTo({ translateY: 0, transition: { type: 'decay', velocity: velocityY } })
    })

I might be missing out on some differences between decay and say spring animation api's within moti, in this case, perhaps an example with decay in the docs could be good?

nandorojo commented 8 months ago

How does reanimated perform if you add these values:


      velocity: 2,
      deceleration: 2,
xzilja commented 8 months ago

It seems to bug out / shoot everything off to the distance 😅

I copied and set up example from reanimated in this expo snack https://snack.expo.dev/@asimetriq/juicy-indigo-raspberries?

Set values back to normal, but you can set velocity and decay to 2 on line ~30 to see the effect

nandorojo commented 8 months ago

Can you try moti@0.26.1?

nandorojo commented 8 months ago

I'm wondering if withDecay is broken on Web altogether from reanimated

xzilja commented 8 months ago

Getting same error on 0.26.1 as well (testing on ios with fresh node_modules install and ios project rebuild)

nandorojo commented 8 months ago

How odd, and it works with plain reanimated?

xzilja commented 8 months ago

Yes, working example is in the snack I provided above by copying from reanimated's docs. (also tested locally on my own implementation).