AnimatePresence + Hermes doesn't work
davidnum opened this issue Β· 28 comments
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
MotiView stuck/freeze appearing animation when wrapped in AnimatedPresence with exitBeforeEnter prop. Patch from #195 and changes in #200 does not fix this bug.
Bug not exists in moti@0.17.1
Steps To Reproduce
- Only happens when MotiView has multiple animated properties:
<MotiView
from={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
/>
- Wrap MotiView into AnimatePresence with
exitBeforeEnter
prop - Enable hermes in Podfile
Versions
- Moti: 0.18.0
- Reanimated: 2.9.1
- React Native: 0.67.4 - 0.69
Screenshots
Current Behavior:
2022-07-26.02.44.09.mov
Expected Behavior:
2022-07-26.02.48.49.mov
Reproduction
Interesting, so this works without Hermes for you? What version of Hermes?
And you're saying that this only happens with Moti 0.18, but not 0.17?
Interesting, so this works without Hermes for you? What version of Hermes?
Expected behavior video recorded without enabling hermes.
Hermes versions: 0.10, 0.11.
And you're saying that this only happens with Moti 0.18, but not 0.17?
Yeah, on 0.17.1 it works as expected.
I see. It looks like this would be caused by the Framer Motion upgrade in moti@0.18.0
:
Could you try adding this to your package.json
?
{
"resolutions": { "framer-motion": "3.9.1" }
}
And then run yarn install --force
I see. It looks like this would be caused by the Framer Motion upgrade in
moti@0.18.0
:Could you try adding this to your
package.json
?{ "resolutions": { "framer-motion": "3.9.1" } }And then run
yarn install --force
Didn't help :(
π§
i canβt see anything else in the change log that would be unique to 0.18 causing problemsβ¦whatβs the full code?
π§
i canβt see anything else in the change log that would be unique to 0.18 causing problemsβ¦whatβs the full code?
Having the same issue on Android (not iOS) on moti 0.18
Not sure but downgrading to moti 0.17.1 fixed the issue.
did you try the yarn resolution?
nah. Was in a time crunch and had to do fastest possible solution
@nandorojo hi, any news?
@nandorojo Resolution doesn't seem to be working.
{
"resolutions": { "framer-motion": "3.9.1" }
}
Another issue that I have is that onExitComplete
never seems to fire on 0.18.0
whenever I provide two types of animations {opacity: 0, translateY: 50}
, however it does work with one value {opacity: 0}
.
Seems to work properly on lower versions. So for now I'm downgrading to 0.17.1
until there is a fix.
Edit:
In 0.17.1
MotiPressable
onPress
event seems to be broken, <Pressable />
from react-native
works, not sure what's going on there.
Thanks for the update. I'll keep looking into it soon when I have some time. I'm convinced it's a dependency-related issue.
Also to add, using sequences with the useDynamicAnimation
hook is broken with Hermes enabled.
For example, the below will not work with the latest Expo (SDK 46) and Hermes enabled (was working before when Hermes was disabled):
import { Pressable } from "native-base";
import { useDynamicAnimation } from "moti";
const animation = useDynamicAnimation(() => {
return {
scale: 1
}
})
<Pressable onPress={() => {
animation.animateTo({
scale: [1.2, { value: 1, type: 'spring' }]
})
}}>
<MotiView state={animation}>
<Text>Placeholder...</Text>
</MotiView>
</Pressable>
I think you are right @nandorojo this being a dependency-related and it might not be scoped to just using AnimatePresence.
Oof Hermes is killing me here! Haha
I feel very sorry for you now, haha π€£
Just a heads up, I've updated the code with the one that actually throws the error, and throws this:
Also, for those strolling here and was stuck like me, what I wanted to achieve it to animate the sequence, I think Hermes with different JS support language features doesn't allow the previous syntax or it could be a react-reanimated issue. Anyways I fixed my issue by tweaking the syntax like this:
import { Pressable } from "native-base";
import { useDynamicAnimation } from "moti";
const animation = useDynamicAnimation(() => {
return {
scale: 1
}
})
<Pressable onPress={() => {
animation.animateTo({
scale: [
{ value: 1.2, type: 'spring', duration: 500 },
{ value: 1, type: 'spring' }
]
})
}}>
<MotiView state={animation}>
<Text>Placeholder...</Text>
</MotiView>
</Pressable>
Having the same issue here, unfortunately π’ .. and for me, trying to downgrade to 0.17.1, is not a possible workaround, because I'm already using the React 18 and with that the children
is missing
I'm experiencing the same issue as well and not using hermes, downgrading to 0.17.1 seems to work for me. I'm using:
- expo 47.0.3
- Moti 0.21.0
- React Native 0.70.5
- React reanimated 2.13.0
With Moti 0.21.0 this does not work:
<AnimatePresence exitBeforeEnter>
<MotiView
key={item.id}
from={{
opacity: 0,
transform: [{ translateY: -10 }],
}}
animate={{
opacity: 1,
transform: [{ translateY: 0 }],
}}
exit={{
opacity: 0,
transform: [{ translateY: -10 }],
}}
transition={{ type: "timing", duration: 400, delay: 50 }}
>
<Text>{item.title}</Text>
</MotiView>
</AnimatePresence>
item
is set via a prop in another component. Code above does work on Moti 0.17.1
could you do me a favor and runyarn why framer-motion
before & after changing moti versions? iβm very curious if framer versions is the cause. I donβt see what else it could be.
Before:
=> Found "framer-motion@3.10.6"
info Reasons this module exists
- "moti#@motify#core" depends on it
- Hoisted from "moti#@motify#core#framer-motion"
info Disk size without dependencies: "4.82MB"
info Disk size with unique dependencies: "6.58MB"
info Disk size with transitive dependencies: "6.58MB"
info Number of shared dependencies: 5
After:
=> Found "framer-motion@6.5.1"
info Reasons this module exists
- "moti" depends on it
- Hoisted from "moti#framer-motion"
info Disk size without dependencies: "2.7MB"
info Disk size with unique dependencies: "5.5MB"
info Disk size with transitive dependencies: "6.57MB"
info Number of shared dependencies: 6
Okay so this must be it. Does the newest version work if you add a yarn resolution to framer 3.10.6?
I've added a resolution to my package.json for framer-motion:
"resolutions": {
"framer-motion": "3.10.6"
}
Then installed the latest Moti and ran yarn why framer-motion
which results in version 3.10.6
. Build and ran my app again but the problem still exists.
Reverted back to 0.17.1, build and ran my app and then it works as intended. When using 0.17.1
I do see that <AnimatePresence>
is underlined in my IDE and when hovered refers to import { Frame, AnimatePresence } from 'framer'
but is imported like so: import { AnimatePresence, MotiView } from "moti"
.
Hm, okay. Still a bit peculiar to me. Will try to figure it out when I can.
Alright, I'm deeply investigating. I've spent hours diffing lock files. Here are some findings.
^0.17.1
works^0.18
does not work
Here is what it looks like to install it:
info Direct dependencies
ββ moti@0.18.0
info All dependencies
ββ @motify/components@0.18.0
ββ @motionone/animation@10.15.1
ββ @motionone/dom@10.12.0
ββ @motionone/easing@10.15.1
ββ @motionone/generators@10.15.1
ββ framer-motion@6.5.1
ββ moti@0.18.0
ββ popmotion@11.0.3
I ran a diff of all files from moti and went one-by-one to see what the cause could be (yes really).
By pulling useMotify
from 0.17
β 0.18
, I found that it started working again. This meant that something in the 0.18
change in the worklets made a difference. In that update, I improved performance by changing .forEach
loops to use for (const key of)
loops. I'm wondering if Hermes didn't like that...
I tried changing for (const key in mergedStyles)
to Object.keys(mergedStyles).forEach(key =>
and...that did it π§.
So, I guess I have to refactor that back. This whole coding thing may not be for me lol
Moti finally works with Hermes in version 0.22
. Please upgrade and let me know if it works for you. Appreciate your patience.