update
This commit is contained in:
115
src/components/product/ProductGallery.tsx
Normal file
115
src/components/product/ProductGallery.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { useRef, useState, useCallback } from "react";
|
||||
import {
|
||||
View,
|
||||
Image,
|
||||
FlatList,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
} from "react-native";
|
||||
import Carousel from "react-native-reanimated-carousel";
|
||||
|
||||
const { width } = Dimensions.get("window");
|
||||
const THUMB_SIZE = 64;
|
||||
const SPACING = 10;
|
||||
|
||||
const images = [
|
||||
require("../../../assets/images/big-product-detail.png"),
|
||||
require("../../../assets/images/big-product-detail.jpg"),
|
||||
require("../../../assets/images/big-product-detail-2.jpg"),
|
||||
require("../../../assets/images/big-product-detail-3.jpg"),
|
||||
require("../../../assets/images/big-product-detail-4.jpg"),
|
||||
];
|
||||
|
||||
const ProductGallery = () => {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const carouselRef = useRef<Carousel<any>>(null);
|
||||
const thumbnailListRef = useRef<FlatList>(null);
|
||||
|
||||
const scrollToThumbnail = useCallback((index: number) => {
|
||||
const offset = index * (THUMB_SIZE + SPACING) - width / 2 + THUMB_SIZE / 2;
|
||||
thumbnailListRef.current?.scrollToOffset({
|
||||
offset: Math.max(0, offset),
|
||||
animated: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onSnapToItem = useCallback(
|
||||
(index: number) => {
|
||||
setActiveIndex(index);
|
||||
scrollToThumbnail(index);
|
||||
},
|
||||
[scrollToThumbnail]
|
||||
);
|
||||
|
||||
const onThumbnailPress = useCallback((index: number) => {
|
||||
carouselRef.current?.scrollTo({ index, animated: true });
|
||||
}, []);
|
||||
|
||||
const renderThumbnail = useCallback(
|
||||
({ item, index }: { item: any; index: number }) => (
|
||||
<TouchableOpacity onPress={() => onThumbnailPress(index)}>
|
||||
<Image
|
||||
source={item}
|
||||
style={[
|
||||
styles.thumbnail,
|
||||
activeIndex === index && styles.activeThumbnail,
|
||||
]}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
),
|
||||
[activeIndex, onThumbnailPress]
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Carousel
|
||||
ref={carouselRef}
|
||||
loop={false}
|
||||
width={width}
|
||||
height={300}
|
||||
data={images}
|
||||
scrollAnimationDuration={400}
|
||||
renderItem={({ item }) => (
|
||||
<Image source={item} style={styles.bigImage} resizeMode="contain" />
|
||||
)}
|
||||
onSnapToItem={onSnapToItem}
|
||||
/>
|
||||
|
||||
<FlatList
|
||||
ref={thumbnailListRef}
|
||||
data={images}
|
||||
horizontal
|
||||
keyExtractor={(_, i) => i.toString()}
|
||||
renderItem={renderThumbnail}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={styles.thumbList}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductGallery;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {},
|
||||
bigImage: {
|
||||
width: width - 40,
|
||||
height: 280,
|
||||
borderWidth: 1,
|
||||
borderColor: "#b1b1b1",
|
||||
borderRadius: 12,
|
||||
},
|
||||
thumbnail: {
|
||||
width: THUMB_SIZE,
|
||||
height: THUMB_SIZE,
|
||||
marginRight: SPACING,
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: "#b1b1b1",
|
||||
},
|
||||
activeThumbnail: {
|
||||
borderColor: "#1877F2",
|
||||
},
|
||||
thumbList: {},
|
||||
});
|
||||
Reference in New Issue
Block a user