Issue with scaling on Animated.ScrollView after scaling-based exit animation
Opened this issue · 0 comments
Description
When using a scale-based exit animations (such as ZoomOut
or any other scale-based animations) on an Animated.ScrollView
, there seems to be an issue where the scale value from the exit animation is cached (?), causing incorrect scaling behavior when the component is remounted. Specifically, after the ZoomOut
animation has been executed, the subsequent ZoomIn
animation does not scale the component up from the correct initial value when the visibility is toggled back on. Instead, it seems to start from the last scale value applied during the exit animation, resulting in the component not scaling properly.
This issue contrasts with other animated components, such as Animated.View
, which correctly triggers both the ZoomIn
and ZoomOut
animations multiple times without retaining the incorrect scale value from the previous exit animation.
Expected Behavior
The ZoomIn
animation should scale the component correctly from its initial state every time the Animated.ScrollView
becomes visible, regardless of whether a ZoomOut
, or any other scale-based exit animations such as custom exit animations, has been triggered previously.
Actual Behavior
The ZoomIn
animation fails to scale the component up from the expected initial state if ZoomOut
has been triggered before. Instead, it uses the last scale value set during the exit animation as the starting value, leading to a progressively smaller component on each toggle. For instance, if the component exits at a scale of 0.8, the next time it enters, it starts from 0.8, which makes the component appear smaller with each visibility toggle.
Code Example
export default function App() {
const [visible, setVisible] = useState(false)
return (
<SafeAreaView style={styles.container}>
{visible && (
<>
<Animated.ScrollView style={styles.content} entering={ZoomIn} exiting={ZoomOut}>
<Text style={styles.paragraph}>
Animated.ScrollView bug
</Text>
</Animated.ScrollView>
<Animated.View style={styles.content} entering={ZoomIn} exiting={ZoomOut}>
<Text style={styles.paragraph}>
Animated.View is working
</Text>
</Animated.View>
</>
)}
<Pressable onPress={() => setVisible(!visible)} style={styles.button}><Text style={styles.paragraph}>Toggle</Text></Pressable>
</SafeAreaView>
);
}
Working code example can be tested in iOS in this snack.
Screen Recording
Animated.View ✅
AnimatedView.mp4
Animated.ScrollView 🐞
AnimatedScrollView.mp4
Steps to reproduce
- Create an
Animated.ScrollView
withZoomIn
for entry andZoomOut
for exit animations. - Toggle the visibility of the
Animated.ScrollView
using a button or another method (test this in an native environment, I have been testing in iOS) - After the
ZoomOut
exit animation runs, toggle the visibility again. - Observe that the
ZoomIn
animation does not scale the component correctly.
Snack or a link to a repository
https://snack.expo.dev/qrAntko0DsnZ0wppqbKKY
Reanimated version
3.6.1
React Native version
0.76.3
Platforms
iOS
JavaScript runtime
None
Workflow
Expo Go
Architecture
None
Build type
None
Device
iOS simulator
Device model
iPhone 15 Pro
Acknowledgements
Yes