I am working with react-native-reanimated-carousel
in a React Native
project, and I want to create a subtle animation when the page first loads. Specifically, I want the carousel to scroll slightly to reveal just a bit of the next item and then smoothly bounce back to the initial position, where only the first item is fully visible.
I have tried using the scrollTo
method, but I can't get the animation to look smooth. The current implementation either reveals too much of the next item or the bounce-back
is too fast and abrupt or does not happen at all.
const carouselRef = useRef(null);
useEffect(() => {
const timeout = setTimeout(() => {
if (carouselRef.current) {
carouselRef.current.scrollTo({
x: 0.2,
animated: true,
animationDuration: 1200,
easing: Easing.out(Easing.quad),
});
setTimeout(() => {
if (carouselRef.current) {
carouselRef.current.scrollTo({
x: 0,
animated: true,
animationDuration: 1200,
easing: Easing.in(Easing.quad),
});
}
}, 1300);
}
}, 500);
}, []);
return (
<Animated.View style={styles.wrapper}>
<Carousel
ref={carouselRef}
panGestureHandlerProps={{
activeOffsetX: [-10, 10],
}}
pagingEnabled
width={ITEM_WIDTH}
height=HEADER_HEIGHT}
data={data}
scrollAnimationDuration={1000}
onProgressChange={onProgressChange}
renderItem={({ item, index }) => (
<Item
active={index === activeIndex}
item={item}
/>
)}
/>
</Animated.View>
);
How can I achieve the partial right scroll?
For anyone wanting to achieve the same effect:
I just created a
const translateX = useRef(new Animated.Value(0)).current;
and put in a useEffect
:
useEffect(() => {
if (!isLoading) {
Animated.sequence([
Animated.timing(translateX, {
toValue: -50,
duration: 1000,
useNativeDriver: true,
}),
Animated.spring(translateX, {
toValue: 0,
duration: 2000,
useNativeDriver: true,
}),
]).start();
}
}, [isLoading]);
and wrapped the item rendering
in the carousel
in
<Animated.View style={{ transform: [{ translateX }] }}>
<Item active={index === activeIndex} item={item}/>
</Animated.View>
This did the animation very smooth and bouncy.