I'm creating a ripple wave animation in React Native with three overlapping circles that should maintain consistent spacing. Initially, the waves animate perfectly with even intervals, but after running for a while (usually 10s), they gradually lose synchronization.
Minimal reproducible code ⬇️ (expo link: https://snack.expo.dev/@real8900/c6cb2e)
import React, { useEffect, useRef } from 'react';
import { View, StyleSheet, Animated, Easing } from 'react-native';
const Wave = ({ startTime, endTime, totalDuration = 2000 }) => {
const scaleAnim = useRef(new Animated.Value(0)).current;
const animationRef = useRef(null);
useEffect(() => {
animationRef.current = Animated.loop(
Animated.sequence([
Animated.delay(startTime),
Animated.timing(scaleAnim, {
toValue: 1,
duration: endTime - startTime,
easing: Easing.linear,
useNativeDriver: true,
}),
Animated.timing(scaleAnim, {
toValue: 0,
duration: 0,
useNativeDriver: true,
}),
Animated.delay(totalDuration - endTime),enter image description here
]),
);
animationRef.current.start();
return () => {
animationRef.current?.stop();
};
}, [startTime, endTime, totalDuration, scaleAnim]);
return (
<Animated.View
style={[
styles.wave,
{ transform: [{ scale: scaleAnim }] },
]}
/>
);
};
const App = () => {
return (
<View style={styles.container}>
<Wave startTime={0} endTime={1300} />
<Wave startTime={300} endTime={1600} />
<Wave startTime={600} endTime={2000} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
wave: {
position: 'absolute',
width: 200,
height: 200,
borderRadius: 100,
borderWidth: 2,
borderColor: '#007AFF',
},
});
export default App;
Expected behavior: The three waves should maintain consistent spacing indefinitely (300ms apart).
Actual behavior: After running for some time, the waves become noticeably out of sync, with uneven spacing between them.
What I've tried:
Using
Animated.loopand manual recursionUsing
Easing.linearto ensure consistent timing
Environment:
React Native: latest Expo React Native
Platform: iOS
Screenshots:
Why does this synchronization drift occur, and how can I ensure the animations stay perfectly synchronized over extended periods?