@garlicbed/react-native-slide360
Version:
A React Native component for interactive 360-degree product views
77 lines (76 loc) • 2.58 kB
JavaScript
;
import { useCallback, useRef, useState, useMemo } from 'react';
import { View, StyleSheet } from 'react-native';
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
import ImagePlaceholder from "./ImagePlaceholder.component.js";
import throttle from 'lodash.throttle';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const Slide360View = ({
images,
dragDeltaX = 20,
height = 200,
containerStyle,
onPressSlide,
fallbackComponent,
children,
disabled
}) => {
const [currentViewIndex, setcurrentViewIndex] = useState(0);
const lastActiveViewIndex = useRef(0);
const currentScrollItemPoint = useRef(undefined);
const totalImages = images.length || 0;
const throttleSetState = useCallback(throttle(newValue => setcurrentViewIndex(() => newValue), 200), []);
const pan = Gesture.Pan().minDistance(1).onUpdate(event => {
let scrollItemPoint = Math.floor(-event.translationX / dragDeltaX);
if (currentScrollItemPoint.current !== scrollItemPoint) {
currentScrollItemPoint.current = scrollItemPoint;
let cursorIndex = scrollItemPoint % totalImages;
if (cursorIndex === -0) {
cursorIndex = 0;
} else if (cursorIndex < 0) {
cursorIndex = Math.abs(cursorIndex + totalImages);
}
const nextSlideIndex = (cursorIndex + lastActiveViewIndex.current) % totalImages;
throttleSetState(nextSlideIndex);
}
}).onEnd(() => {
lastActiveViewIndex.current = currentViewIndex;
}).runOnJS(true);
const renderImage = useMemo(() => {
const handleOnPressImage = props => onPressSlide?.({
...props,
index: currentViewIndex
});
return /*#__PURE__*/_jsx(ImagePlaceholder, {
source: images[currentViewIndex],
height: height,
onPressImage: handleOnPressImage,
fallbackComponent: fallbackComponent,
disabled: disabled
});
}, [currentViewIndex, images, height, onPressSlide]);
const rootContainerStyle = [styles.container, {
height
}, containerStyle];
return /*#__PURE__*/_jsx(GestureHandlerRootView, {
style: rootContainerStyle,
children: /*#__PURE__*/_jsx(GestureDetector, {
gesture: pan,
children: /*#__PURE__*/_jsxs(View, {
collapsable: false,
children: [renderImage, children]
})
})
});
};
const styles = StyleSheet.create({
container: {
width: '100%',
backgroundColor: 'white'
},
childrenContainer: {
position: 'absolute'
}
});
export default Slide360View;
//# sourceMappingURL=index.js.map