Skip to content

Instantly share code, notes, and snippets.

@mattThousand
Created January 3, 2021 18:27
Show Gist options
  • Select an option

  • Save mattThousand/634aa14de295140a9e2995fcf34054cc to your computer and use it in GitHub Desktop.

Select an option

Save mattThousand/634aa14de295140a9e2995fcf34054cc to your computer and use it in GitHub Desktop.
import React, {FunctionComponent, useRef} from 'react';
import {
Animated,
Dimensions,
FlatList,
Image,
StyleSheet,
View,
} from 'react-native';
const images: string[] = [
'https://media.tenor.com/images/3704f2b9b8b66a5747116f436a5e6aba/tenor.gif',
'https://media.tenor.com/images/78feaf65c477ead06981dca74c3ead14/tenor.gif',
'https://media.tenor.com/images/425213c8ada06900931c2d0213389ae4/tenor.gif',
];
const {width} = Dimensions.get('screen');
const CustomPageControl: FunctionComponent = () => {
const animatedValue = useRef(new Animated.Value(0)).current;
return (
<View style={style.container}>
<View style={style.topContainer}>
<Animated.FlatList
data={images}
horizontal
showsHorizontalScrollIndicator={false}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: animatedValue}}}],
{useNativeDriver: false},
)}
pagingEnabled={true}
keyExtractor={(_, index) => index.toString()}
renderItem={({item}) => {
return (
<View style={style.imageContainer}>
<Image style={style.image} source={{uri: item}} />
</View>
);
}}
/>
</View>
<View style={style.bottomContainer}>
<FlatList
horizontal
data={images}
keyExtractor={(_, index) => index.toString()}
renderItem={({index}) => {
const inputRange = [
(index - 1) * width,
index * width,
(index + 1) * width,
];
const colorOutputRange = ['#000', 'cyan', '#000'];
const scaleOutputRange = [1, 2, 1];
const dotScale = animatedValue.interpolate({
inputRange,
outputRange: scaleOutputRange,
extrapolate: 'clamp',
});
const color = animatedValue.interpolate({
inputRange,
outputRange: colorOutputRange,
extrapolate: 'clamp',
});
return (
<View style={style.dotContainer}>
<PagingDot color={color} scale={dotScale} />
</View>
);
}}
/>
</View>
</View>
);
};
const PagingDot: FunctionComponent<{scale; color}> = ({scale, color}) => {
return (
<Animated.View
style={[style.pagingDot, {backgroundColor: color, transform: [{scale}]}]}
/>
);
};
const style = StyleSheet.create({
container: {
flex: 3,
},
topContainer: {
flex: 2,
},
bottomContainer: {
flex: 1,
width,
justifyContent: 'flex-start',
alignItems: 'center',
},
imageContainer: {
justifyContent: 'flex-end',
paddingBottom: 40,
alignItems: 'center',
width,
},
image: {
width: width - 80,
height: 300,
borderRadius: 40,
},
pagingDot: {
width: 14,
height: 14,
backgroundColor: 'cyan',
borderRadius: 7,
borderWidth: 2,
borderColor: '#000',
},
dotContainer: {
width: 50,
padding: 10,
},
});
export default CustomPageControl;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment