Files
bestpc_mobile/src/components/buildpc/ImageGallery.tsx

116 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-07-21 09:00:48 +07:00
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 ImageGallery = () => {
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 ImageGallery;
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: {},
});