react-native-expo-cropper 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ImageCropper.js +41 -5
package/package.json
CHANGED
package/src/ImageCropper.js
CHANGED
|
@@ -20,6 +20,7 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
|
|
|
20
20
|
|
|
21
21
|
const [isLoading, setIsLoading] = useState(false);
|
|
22
22
|
const [showFullScreenCapture, setShowFullScreenCapture] = useState(false);
|
|
23
|
+
const lastValidPosition = useRef(null);
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
|
|
@@ -94,24 +95,59 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
|
|
|
94
95
|
if (!image || showResult) return;
|
|
95
96
|
const now = Date.now();
|
|
96
97
|
const { locationX: tapX, locationY: tapY } = e.nativeEvent;
|
|
98
|
+
|
|
97
99
|
if (lastTap.current && now - lastTap.current < 300) {
|
|
98
100
|
const exists = points.some(p => Math.abs(p.x - tapX) < 15 && Math.abs(p.y - tapY) < 15);
|
|
99
101
|
if (!exists) setPoints([...points, { x: tapX, y: tapY }]);
|
|
100
102
|
lastTap.current = null;
|
|
101
103
|
} else {
|
|
102
104
|
const index = points.findIndex(p => Math.abs(p.x - tapX) < 20 && Math.abs(p.y - tapY) < 20);
|
|
103
|
-
if (index !== -1)
|
|
105
|
+
if (index !== -1) {
|
|
106
|
+
selectedPointIndex.current = index;
|
|
107
|
+
lastValidPosition.current = { ...points[index] }; // store original position before move
|
|
108
|
+
}
|
|
104
109
|
lastTap.current = now;
|
|
105
110
|
}
|
|
106
111
|
};
|
|
107
112
|
|
|
108
113
|
const handleMove = (e) => {
|
|
109
114
|
if (showResult || selectedPointIndex.current === null) return;
|
|
115
|
+
|
|
110
116
|
const { locationX: moveX, locationY: moveY } = e.nativeEvent;
|
|
111
|
-
const
|
|
112
|
-
const
|
|
117
|
+
const width = imageMeasure.current.width;
|
|
118
|
+
const height = imageMeasure.current.height;
|
|
119
|
+
|
|
120
|
+
const boundedX = Math.max(0, Math.min(moveX, width));
|
|
121
|
+
const boundedY = Math.max(0, Math.min(moveY, height));
|
|
122
|
+
|
|
123
|
+
const edgeThreshold = 10;
|
|
124
|
+
const isNearTopOrBottomEdge =
|
|
125
|
+
boundedY <= edgeThreshold || boundedY >= height - edgeThreshold;
|
|
126
|
+
|
|
127
|
+
const isNearLeftOrRightEdge =
|
|
128
|
+
boundedX <= edgeThreshold || boundedX >= width - edgeThreshold;
|
|
129
|
+
|
|
130
|
+
if (isNearTopOrBottomEdge || isNearLeftOrRightEdge) {
|
|
131
|
+
// Reset point to last known position
|
|
132
|
+
if (lastValidPosition.current && selectedPointIndex.current !== null) {
|
|
133
|
+
setPoints(prev =>
|
|
134
|
+
prev.map((p, i) =>
|
|
135
|
+
i === selectedPointIndex.current ? lastValidPosition.current : p
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
selectedPointIndex.current = null;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Valid move — update point and store as new last valid position
|
|
144
|
+
const updatedPoint = { x: boundedX, y: boundedY };
|
|
145
|
+
lastValidPosition.current = updatedPoint;
|
|
146
|
+
|
|
113
147
|
setPoints(prev =>
|
|
114
|
-
prev.map((p, i) =>
|
|
148
|
+
prev.map((p, i) =>
|
|
149
|
+
i === selectedPointIndex.current ? updatedPoint : p
|
|
150
|
+
)
|
|
115
151
|
);
|
|
116
152
|
};
|
|
117
153
|
|
|
@@ -197,7 +233,7 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
|
|
|
197
233
|
<Svg style={styles.overlay}>
|
|
198
234
|
<Path
|
|
199
235
|
d={`M 0 0 H ${imageMeasure.current.width} V ${imageMeasure.current.height} H 0 Z ${createPath()}`}
|
|
200
|
-
fill={showResult ? '
|
|
236
|
+
fill={showResult ? 'white' : 'rgba(255, 255, 255, 0.8)'}
|
|
201
237
|
fillRule="evenodd"
|
|
202
238
|
/>
|
|
203
239
|
{!showResult && points.length > 0 && (
|