So essentially, I want to play the lottie animation everytime it is tapped. Here is my UI code for the lottie animation:
<Pressable onPress={playGame}>
<LottieView
ref={loseAnimationRef}
style={styles.egg}
source={Lost}
autoPlay={false}
loop={false}
onAnimationFinish={() => {
resetAnimation();
}}
/>
</Pressable>
Here is my state code for the lottie animation:
const loseAnimationRef = useRef(null);
const playGame = async () => {
await mainGameLogicUC();
playAnimation()
};
const playAnimation = () => {
loseAnimationRef.current.play()
}
const resetAnimation = () => {
loseAnimationRef.current.reset()
}
On the first tap, the animation play perfefctly fine. But on all other taps, the animation won't play. I tried pausing the animation in the onAnimationFinish
and then resuming it, but that also didn't work. Am I missing something?
I got rid of the resetAnimation()
in the onAnimationFinish
and that solved the initial problem. But the thing is, I want the animation to be reset to the beginning every time. Why does it break when I reset the animation?
After coming back to this problem a few days later, I found the solution
Playing the lottie animation seems to be considered a side effect, therefore, editing the references to the animations should be done in a useEffect
hook
The solution that worked for me:
(again, in this code, I want the animation to reset to the beginning before the user taps the screen screen again.
state code
const isMounted = useRef(false);
const [isWonAnimationShowing, setIsWonAnimationShowing] = useState(false);
const [isAnimationPlaying, setIsAnimationPlaying] = useState(false);
const loseAnimationRef = useRef(null);
const winAnimationRef = useRef(null);
useEffect(() => {
if (isMounted.current) {
if (isAnimationPlaying) {
_playAnimation();
} else {
_resetAnimation();
}
} else {
isMounted.current = true;
}
}, [isAnimationPlaying]);
const playAnimation = () => {
setIsAnimationPlaying(true);
};
const _playAnimation = () => {
if (isWonAnimationShowing) {
winAnimationRef.current.play();
} else {
loseAnimationRef.current.play();
}
};
const resetAnimation = () => {
setIsAnimationPlaying(false);
};
const _resetAnimation = () => {
if (isWonAnimationShowing) {
winAnimationRef.current.reset();
} else {
loseAnimationRef.current.reset();
}
};
UI code
<View style={styles.body}>
<Pressable disabled={isAnimationPlaying} onPress={playGame}>
{isWonAnimationShowing ? (
<LottieView
ref={winAnimationRef}
style={styles.egg}
source={Won}
autoPlay={false}
loop={false}
onAnimationFinish={() => {
resetAnimation();
}}
/>
) : (
<LottieView
ref={loseAnimationRef}
style={styles.egg}
source={Lost}
autoPlay={false}
loop={false}
onAnimationFinish={() => {
resetAnimation();
}}
/>
)}
</Pressable>
</View>