I am trying to implement this carousel in React Native
and use React Native Animated to implement it. I wrote the code as follows
const itemSize = AppDevice.width / 4;
const marginValue = 5;
const HomeScreen = ({navigation}) => {
let videoRef = useRef();
const scrollX = useRef(new Animated.Value(0)).current;
const marginX = useRef(new Animated.Value(0)).current;
let carouselRef = useRef();
let [loading, setLoading] = useState(true);
let [MainCategory, setMainCategory] = useState();
let [currentIndex, setcurrentIndex] = useState();
useEffect(() => {
const renderCarousel = () => {
return (
<Animated.FlatList
data={MainCategory}
horizontal
showsHorizontalScrollIndicator={false}
snapToInterval={itemSize + marginValue * 2}
bounces={false}
decelerationRate={0}
style={{backgroundColor: 'red'}}
scrollEventThrottle={16}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: scrollX}}}],
{useNativeDriver: true},
)}
onMomentumScrollEnd={e =>
setcurrentIndex(
Math.ceil(
e.nativeEvent.contentOffset.x /(itemSize + marginValue * 2),//to find active item
),
)
}
renderItem={({item, index}) => {
const inputRange = [
(index - 2) * (itemSize + marginValue * 2), //Before 2 items of the active item
(index - 1) * (itemSize + marginValue * 2), //Before 1 items of the active item
index * (itemSize + marginValue * 2), //active item
(index + 1) * (itemSize + marginValue * 2),//after 1 items of the active item
(index + 2) * (itemSize + marginValue * 2),//after 2 items of the active item
];
const translateY = scrollX.interpolate({ //To change the size of items
inputRange,
outputRange: [0.6, 0.9, 1.25, 0.9, 0.6],
});
const inputRange2 = [
(index - 2) * (itemSize + marginValue),
(index - 1) * (itemSize + marginValue),
index * (itemSize + marginValue),
(index + 1) * (itemSize + marginValue),
(index + 2) * (itemSize + marginValue),
];
const margin = marginX.interpolate({ //to add margine to items ((Here it does
not work as expectedcorrectly
inputRange,
outputRange: [-20, 10, 0, 10, -20], //
});
return (
<Animated.View
style={{
marginTop: 50,
width: itemSize,
height: itemSize,
justifyContent: 'space-between',
marginHorizontal:
index != 0 && index + 1 != MainCategory.length //to center first item
? marginValue
: 0,
marginStart:
index == 0
? itemSize * 2 - itemSize / 2 + marginValue
: marginValue,
marginEnd: //to center last item
index + 1 == MainCategory.length
? itemSize + itemSize / 2 - marginValue
: marginValue,
padding: 20,
borderRadius: 20,
backgroundColor: '#FFF',
transform: [{scale: translateY}, {translateX: margin}],
}}>
<Image
style={{width: '100%', height: '100%', resizeMode: 'contain'}}
source={require('../assets/images/open-box.png')}
/>
</Animated.View>
);
}}
/>
);
};
return (
<View style={{flex: 1}}>
{renderCarousel()}
</View>
);
};
The size changes as expected, but the problem is that I want to leave spaces between the elements, but it does not work for me as expected
Is there anyone who can help me, thanks in advance
I finally found I just replaced the ref, from marginX
to scrollX