UNPKG

react-native-gallery-preview

Version:

<div> <img align="right" height="720" src="example.gif"> </div>

149 lines (148 loc) 5.49 kB
"use strict"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Dimensions, I18nManager, StyleSheet, useWindowDimensions, View } from "react-native"; import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue, withDelay, withTiming } from "react-native-reanimated"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { SPRING_CONFIG, MAX_SCALE } from "../../constants"; import { DefaultHeader } from "../DefaultHeader/DefaultHeader"; import { GalleryStatusBar } from "../GalleryStatusBar/GalleryStatusBar"; import { ModalContainer } from "../ModalContainer/ModalContainer"; import { GalleryChildrenItem } from "./GalleryChildrenItem"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; export const GalleryPreviewForChildren = ({ isVisible, onRequestClose, initialIndex = 0, gap = 24, simultaneousRenderedImages = 6, OverlayComponent = DefaultHeader, springConfig = SPRING_CONFIG, maxScale = MAX_SCALE, doubleTabEnabled = true, pinchEnabled = true, swipeToCloseEnabled = true, backgroundColor = "#000", headerTextColor = "#fff", children }) => { const rtl = I18nManager.isRTL; const dimensions = useWindowDimensions(); const [index, setIndex] = useState(initialIndex); const [isFocused, setIsFocused] = useState(true); const translateX = useSharedValue(initialIndex * -(dimensions.width + gap) * (rtl ? -1 : 1)); const opacity = useSharedValue(1); const currentIndex = useSharedValue(initialIndex); useAnimatedReaction(() => currentIndex.value, newIndex => { runOnJS(setIndex)(newIndex); }, [currentIndex]); const wrapperAnimatedStyle = useAnimatedStyle(() => ({ opacity: opacity.value }), [isFocused]); const containerAnimatedStyle = useAnimatedStyle(() => ({ transform: [{ translateX: translateX.value }] })); const listOfChildren = useMemo(() => { return children ? React.Children.toArray(children) : []; }, [children]); const isChildrenVisible = useCallback(imageIndex => { const halfVisible = Math.floor(simultaneousRenderedImages / 2); const start = Math.max(0, index - halfVisible); const end = Math.min(listOfChildren.length - 1, start + simultaneousRenderedImages - 1); return imageIndex >= start && imageIndex <= end; }, [listOfChildren.length, index, simultaneousRenderedImages]); const getImagePositionX = useCallback(i => { return i * -(Dimensions.get("window").width + gap) * (rtl ? -1 : 1); }, [gap, rtl]); useEffect(() => { if (isVisible) { opacity.value = 1; currentIndex.value = initialIndex; translateX.value = getImagePositionX(initialIndex); setIsFocused(true); } }, [currentIndex, getImagePositionX, initialIndex, isVisible, opacity, translateX]); useEffect(() => { const subscription = Dimensions.addEventListener("change", ({ window }) => { const { width } = window; translateX.value = withDelay(0, withTiming(currentIndex.value * -(width + gap) * (rtl ? -1 : 1))); }); return () => { subscription.remove(); }; }, [currentIndex.value, gap, rtl, translateX]); return /*#__PURE__*/_jsxs(ModalContainer, { isVisible: isVisible, onRequestClose: onRequestClose, children: [/*#__PURE__*/_jsx(GalleryStatusBar, { isFocused: isFocused, backgroundColor: backgroundColor }), /*#__PURE__*/_jsxs(Animated.View, { style: [wrapperAnimatedStyle, styles.wrapper, { backgroundColor }], children: [/*#__PURE__*/_jsx(GestureHandlerRootView, { style: styles.gestureContainer, children: /*#__PURE__*/_jsx(Animated.View, { style: [containerAnimatedStyle, styles.container, { columnGap: gap }], children: listOfChildren.map((child, i) => { const visible = isChildrenVisible(i); return /*#__PURE__*/_jsx(View, { style: { ...dimensions }, children: visible && /*#__PURE__*/_jsx(GalleryChildrenItem, { index: i, currentIndex: currentIndex, isFirst: i === 0, isLast: i === listOfChildren.length - 1, rootTranslateX: translateX, opacity: opacity, width: dimensions.width, height: dimensions.height, dataLength: listOfChildren.length, gap: gap, onClose: onRequestClose, isFocused: isFocused, setIsFocused: setIsFocused, springConfig: springConfig, maxScale: maxScale, swipeToCloseEnabled: swipeToCloseEnabled, pinchEnabled: pinchEnabled, doubleTabEnabled: doubleTabEnabled, rtl: rtl, children: child }) }, i); }) }) }), /*#__PURE__*/_jsx(OverlayComponent, { isFocused: isFocused, imagesLength: listOfChildren.length, currentImageIndex: index, onClose: onRequestClose, containerBackgroundColor: backgroundColor, textColor: headerTextColor })] })] }); }; const styles = StyleSheet.create({ wrapper: { flex: 1 }, gestureContainer: { flex: 1 }, container: { flexDirection: "row" } }); //# sourceMappingURL=GalleryPreviewForChildren.js.map