-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
110 lines (96 loc) Β· 3.29 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import React, {
useState,
useRef,
ReactNode
} from 'react';
import {
View,
Image,
PanResponder,
} from 'react-native';
import { Cursor } from './Cursor';
/**
* This is a library that shows images at 350 degrees.
* @param {string[]} images
* - Array with URI images to rotate.
* @param {number} height
* - Image height default is 250.
* @param {number} width
* - Image width default is 250.
* @param {number} rotationRatio
* - The drag distance compares to 180 degree.
* Example: width / rotationRatio = 180 degree. The value default is 0.5.
* @param {string} resizeMode
* - Image display mode. Default is contain.
* @param {number} cursorSize
* - Cursor size.
* @param {ReactNode} cursorIcon
* - Content or icon.
* @param {string} primaryColor
* - First color of the gradient line. The value default is #DA0000
* @param {string} secondaryColor
* - Second color of the gradient line. The value default is #EA8C8A
* @param {string} stopColor
* - End color of the gradient line. The value default is #FFF
*/
export function Image360viewer({
images,
height = 250,
width = 250,
rotationRatio = 0.5,
resizeMode = 'contain',
cursorSize = 40,
cursorIcon,
primaryColor = '#DA0000',
secondaryColor = '#EA8C8A',
stopColor = '#FFF',
}) {
const [cursorCurrentPosition, setCursorCurrentPosition] = useState(cursorSize);
const [imageIndexSelected, setImageIndexSelected] = useState(0);
const rotation = useRef({ value: width / 2 });
const startRotation = useRef({ value: 0 });
const rotatePeriod = useRef({ value: 360 / images.length });
const startPositionXAxis = useRef({ value: 0 });
const currentPositionXAxis = useRef({ value: 0 });
const panResponder = useRef(PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: (_, gestureState) => {
startPositionXAxis.current.value = gestureState.moveX;
},
onPanResponderMove: (_, gestureState) => {
handleUpdateRotation(gestureState);
},
onPanResponderRelease: (_, gestureState) => {
handleUpdateRotation(gestureState);
}
})).current;
function handleUpdateRotation(gestureState) {
startPositionXAxis.current.value = gestureState.moveX;
const deltaRotation = (currentPositionXAxis.current.value - startPositionXAxis.current.value) * 180 / (rotationRatio * width);
rotation.current.value = startRotation.current.value + deltaRotation;
const mRotation = rotation.current.value - Math.floor(rotation.current.value / 360) * 360;
const rotationByImages = Math.floor(mRotation / rotatePeriod.current.value);
setImageIndexSelected(rotationByImages);
if ((gestureState.moveX - (cursorSize / 2)) > 0 && gestureState.moveX < (width - (cursorSize / 2))) {
setCursorCurrentPosition(gestureState.moveX);
}
}
return (
<View {...panResponder.panHandlers} style={{ width: '100%', alignItems: 'center' }}>
<Image
source={{ uri: images[imageIndexSelected] }}
style={{ width, height }}
resizeMode={resizeMode}
/>
<Cursor
width={cursorSize}
cursorCurrentPosition={cursorCurrentPosition}
cursorIcon={cursorIcon}
color={primaryColor}
primaryColor={primaryColor}
secondaryColor={secondaryColor}
stopColor={stopColor}
/>
</View>
);
}