I'm new with react native, and I found the Animated in react-native, so there is a carousel with images. I can just swipe it horizontally, but I want it also can auto scroll by default.. and when it becomes to last slider it should starts from first slider with animations.. please help me out the solution, thank you very much!
Carousel.js (shared code here - https://codeshare.io/G8EZOZ):
import React, { useCallback, useEffect, useRef, useState } from 'react'
import {
SafeAreaView,
ScrollView,
StyleSheet,
View,
ImageBackground,
Animated,
useWindowDimensions,
Alert,
Pressable,
} from 'react-native'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import i18next from 'i18next'
import * as slidersAction from '../../store/actions/sliders'
import Loading from './Loading'
const Carousel = (props) => {
const scrollX = useRef(new Animated.Value(0)).current
const lang = i18next.language
const { width: windowWidth } = useWindowDimensions()
const { t, i18n } = useTranslation()
const [error, setError] = useState()
const [isLoading, setisLoading] = useState(false)
const dispatch = useDispatch()
const images = useSelector((state) => state.sliders.availableSliders)
const loadSliders = useCallback(async () => {
setisLoading(true)
setError(null)
try {
await dispatch(slidersAction.fetchSliders(t('sliders.errorMessageFetch')))
} catch (err) {
setError(err)
}
setisLoading(false)
})
useEffect(() => {
loadSliders()
}, [])
if (error) {
Alert.alert(t('sliders.errorTitle'), t('sliders.errorMessageFetch'), [{ text: 'Ок' }])
setError(null)
}
if (isLoading) {
return <Loading />
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.scrollContainer}>
<ScrollView
horizontal={true}
style={styles.scrollViewStyle}
pagingEnabled
showsHorizontalScrollIndicator={false}
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: {
x: scrollX,
},
},
},
],
{ useNativeDriver: false }
)}
scrollEventThrottle={1}
>
{images.map((image, imageIndex) => {
return (
<Pressable
key={imageIndex}
onPress={() =>
+image.enableLink
? props.navigation.navigate('Home', {
categoryId: image.categoryId,
categoryTitle: image.title,
categoryTitleKg: image.titleKg,
lang: lang,
})
: {}
}
>
<View style={{ width: windowWidth, height: 100, maxHeight: 160 }}>
<ImageBackground
source={{ uri: image.imageUrl }}
style={styles.card}
resizeMode='contain'
/>
</View>
</Pressable>
)
})}
</ScrollView>
<View style={styles.indicatorContainer}>
{images.map((image, imageIndex) => {
const width = scrollX.interpolate({
inputRange: [
windowWidth * (imageIndex - 1),
windowWidth * imageIndex,
windowWidth * (imageIndex + 1),
],
outputRange: [8, 16, 8],
extrapolate: 'clamp',
})
return <Animated.View key={imageIndex} style={[styles.normalDot, { width }]} />
})}
</View>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
scrollContainer: {
alignItems: 'center',
justifyContent: 'center',
},
card: {
flex: 1,
overflow: 'hidden',
alignItems: 'center',
justifyContent: 'center',
},
normalDot: {
height: 8,
width: 8,
borderRadius: 4,
backgroundColor: 'silver',
marginHorizontal: 4,
},
indicatorContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
marginBottom: 1,
},
})
export default Carousel