react-native-expo-cropper 1.2.52 → 1.3.53
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/dist/CustomCamera.js +164 -55
- package/dist/ImageCropper.js +133 -428
- package/dist/ImageCropperStyles.js +152 -182
- package/package.json +1 -1
- package/src/CustomCamera.js +147 -54
- package/src/ImageCropper.js +161 -430
- package/src/ImageCropperStyles.js +159 -199
package/dist/ImageCropper.js
CHANGED
|
@@ -24,18 +24,14 @@ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArra
|
|
|
24
24
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
25
25
|
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
26
26
|
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
27
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
28
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
29
|
-
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
30
|
-
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
31
|
-
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
32
27
|
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
33
28
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
34
29
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
35
30
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
36
31
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
37
32
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
38
|
-
var PRIMARY_GREEN = '#
|
|
33
|
+
var PRIMARY_GREEN = '#689F38';
|
|
34
|
+
var ACCENT_GREEN = '#689F38';
|
|
39
35
|
|
|
40
36
|
// Base dimension for responsive scaling (e.g. ~375pt design width)
|
|
41
37
|
var RESPONSIVE_BASE = 375;
|
|
@@ -47,10 +43,14 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
47
43
|
addheight = _ref.addheight,
|
|
48
44
|
rotationLabel = _ref.rotationLabel,
|
|
49
45
|
onCancel = _ref.onCancel,
|
|
46
|
+
_ref$cancelText = _ref.cancelText,
|
|
47
|
+
cancelText = _ref$cancelText === void 0 ? 'Cancel' : _ref$cancelText,
|
|
50
48
|
_ref$confirmText = _ref.confirmText,
|
|
51
|
-
confirmText = _ref$confirmText === void 0 ? '
|
|
49
|
+
confirmText = _ref$confirmText === void 0 ? 'Use Scan' : _ref$confirmText,
|
|
52
50
|
_ref$resetText = _ref.resetText,
|
|
53
|
-
resetText = _ref$resetText === void 0 ? '
|
|
51
|
+
resetText = _ref$resetText === void 0 ? 'Enhance' : _ref$resetText,
|
|
52
|
+
_ref$rotateText = _ref.rotateText,
|
|
53
|
+
rotateText = _ref$rotateText === void 0 ? 'Rotate' : _ref$rotateText,
|
|
54
54
|
_ref$cameraInstructio = _ref.cameraInstructionText,
|
|
55
55
|
cameraInstructionText = _ref$cameraInstructio === void 0 ? 'Place the tray inside the green box' : _ref$cameraInstructio;
|
|
56
56
|
var _useWindowDimensions = (0, _reactNative.useWindowDimensions)(),
|
|
@@ -682,64 +682,17 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
682
682
|
} : null;
|
|
683
683
|
};
|
|
684
684
|
var handleTap = function handleTap(e) {
|
|
685
|
-
if (!image || showResult) return;
|
|
685
|
+
if (!image || showResult || points.length === 0) return;
|
|
686
686
|
var now = Date.now();
|
|
687
687
|
var _e$nativeEvent = e.nativeEvent,
|
|
688
688
|
tapX = _e$nativeEvent.locationX,
|
|
689
689
|
tapY = _e$nativeEvent.locationY;
|
|
690
|
-
|
|
691
|
-
// ✅ RÉFÉRENTIEL UNIQUE : Utiliser imageDisplayRect (zone réelle de l'image dans le wrapper)
|
|
692
|
-
// Les coordonnées du tap sont relatives au wrapper commun
|
|
693
|
-
var imageRect = imageDisplayRect.current;
|
|
694
|
-
var wrapper = commonWrapperLayout.current;
|
|
695
|
-
|
|
696
|
-
// Recalculate if not available
|
|
697
|
-
if (imageRect.width === 0 || imageRect.height === 0) {
|
|
698
|
-
if (wrapper.width > 0 && wrapper.height > 0 && originalImageDimensions.current.width > 0) {
|
|
699
|
-
updateImageDisplayRect(wrapper.width, wrapper.height);
|
|
700
|
-
imageRect = imageDisplayRect.current;
|
|
701
|
-
}
|
|
702
|
-
// If still not available, use full wrapper as fallback (wrapper-relative coords)
|
|
703
|
-
if (imageRect.width === 0 || imageRect.height === 0) {
|
|
704
|
-
if (wrapper.width > 0 && wrapper.height > 0) {
|
|
705
|
-
imageRect = {
|
|
706
|
-
x: 0,
|
|
707
|
-
y: 0,
|
|
708
|
-
width: wrapper.width,
|
|
709
|
-
height: wrapper.height
|
|
710
|
-
};
|
|
711
|
-
} else {
|
|
712
|
-
console.warn("⚠️ Cannot handle tap: wrapper or imageDisplayRect not available");
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
// ✅ Clamp to real displayed image content (imageDisplayRect dans le wrapper)
|
|
719
|
-
// Les coordonnées tapX/tapY et imageRect sont RELATIVES au wrapper commun (origine 0,0)
|
|
720
|
-
var _x$y$width$height = {
|
|
721
|
-
x: imageRect.x,
|
|
722
|
-
y: imageRect.y,
|
|
723
|
-
width: imageRect.width,
|
|
724
|
-
height: imageRect.height
|
|
725
|
-
},
|
|
726
|
-
cx = _x$y$width$height.x,
|
|
727
|
-
cy = _x$y$width$height.y,
|
|
728
|
-
cw = _x$y$width$height.width,
|
|
729
|
-
ch = _x$y$width$height.height;
|
|
730
|
-
// ✅ Responsive select radius: scales with screen so touch target matches handle size
|
|
731
|
-
var selectRadius = Math.max(28, Math.round(50 * responsiveScale));
|
|
732
|
-
|
|
733
|
-
// ✅ CRITICAL: Check for existing point selection FIRST (using raw tap coordinates)
|
|
734
|
-
// Don't clamp tapX/Y for point selection - points can be anywhere in wrapper now
|
|
690
|
+
var selectRadius = Math.max(18, Math.round(26 * responsiveScale));
|
|
735
691
|
var index = points.findIndex(function (p) {
|
|
736
692
|
return Math.abs(p.x - tapX) < selectRadius && Math.abs(p.y - tapY) < selectRadius;
|
|
737
693
|
});
|
|
738
694
|
if (index !== -1) {
|
|
739
|
-
// ✅ Point found - select it for dragging
|
|
740
695
|
selectedPointIndex.current = index;
|
|
741
|
-
|
|
742
|
-
// Store initial positions
|
|
743
696
|
initialTouchPosition.current = {
|
|
744
697
|
x: tapX,
|
|
745
698
|
y: tapY
|
|
@@ -748,72 +701,26 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
748
701
|
x: tapX,
|
|
749
702
|
y: tapY
|
|
750
703
|
};
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
// Calculate offset between point and touch at drag start
|
|
755
|
-
touchOffset.current = {
|
|
756
|
-
x: points[index].x - tapX,
|
|
757
|
-
y: points[index].y - tapY
|
|
758
|
-
};
|
|
759
|
-
console.log("🎯 DRAG START - Offset calculated:", {
|
|
760
|
-
pointX: points[index].x.toFixed(2),
|
|
761
|
-
pointY: points[index].y.toFixed(2),
|
|
762
|
-
touchX: tapX.toFixed(2),
|
|
763
|
-
touchY: tapY.toFixed(2),
|
|
764
|
-
offsetX: touchOffset.current.x.toFixed(2),
|
|
765
|
-
offsetY: touchOffset.current.y.toFixed(2)
|
|
766
|
-
});
|
|
704
|
+
lastTap.current = now;
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
767
707
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
var isDoubleTap = lastTap.current && now - lastTap.current < 300;
|
|
785
|
-
if (isDoubleTap && points.length >= 2) {
|
|
786
|
-
// Find closest point on frame lines
|
|
787
|
-
var lineResult = findClosestPointOnFrame(tapX, tapY, 30); // 30px tolerance
|
|
788
|
-
|
|
789
|
-
if (lineResult) {
|
|
790
|
-
var point = lineResult.point,
|
|
791
|
-
insertIndex = lineResult.insertIndex;
|
|
792
|
-
|
|
793
|
-
// Check if a point already exists very close to this position
|
|
794
|
-
var exists = points.some(function (p) {
|
|
795
|
-
return Math.abs(p.x - point.x) < selectRadius && Math.abs(p.y - point.y) < selectRadius;
|
|
796
|
-
});
|
|
797
|
-
if (!exists) {
|
|
798
|
-
// Insert new point at the correct position in the polygon
|
|
799
|
-
var newPoints = _toConsumableArray(points);
|
|
800
|
-
newPoints.splice(insertIndex, 0, point);
|
|
801
|
-
setPoints(newPoints);
|
|
802
|
-
console.log("✅ New point created on frame line:", {
|
|
803
|
-
tap: {
|
|
804
|
-
x: tapX.toFixed(2),
|
|
805
|
-
y: tapY.toFixed(2)
|
|
806
|
-
},
|
|
807
|
-
newPoint: {
|
|
808
|
-
x: point.x.toFixed(2),
|
|
809
|
-
y: point.y.toFixed(2)
|
|
810
|
-
},
|
|
811
|
-
insertIndex: insertIndex,
|
|
812
|
-
totalPoints: newPoints.length
|
|
813
|
-
});
|
|
814
|
-
lastTap.current = null; // Reset to prevent triple-tap
|
|
815
|
-
return;
|
|
816
|
-
}
|
|
708
|
+
// Restore UX: double tap near an edge inserts a new draggable point.
|
|
709
|
+
var isDoubleTap = lastTap.current && now - lastTap.current < 300;
|
|
710
|
+
if (isDoubleTap && points.length >= 2) {
|
|
711
|
+
var lineResult = findClosestPointOnFrame(tapX, tapY, 30);
|
|
712
|
+
if (lineResult) {
|
|
713
|
+
var point = lineResult.point,
|
|
714
|
+
insertIndex = lineResult.insertIndex;
|
|
715
|
+
var exists = points.some(function (p) {
|
|
716
|
+
return Math.abs(p.x - point.x) < selectRadius && Math.abs(p.y - point.y) < selectRadius;
|
|
717
|
+
});
|
|
718
|
+
if (!exists) {
|
|
719
|
+
var newPoints = _toConsumableArray(points);
|
|
720
|
+
newPoints.splice(insertIndex, 0, point);
|
|
721
|
+
setPoints(newPoints);
|
|
722
|
+
lastTap.current = null;
|
|
723
|
+
return;
|
|
817
724
|
}
|
|
818
725
|
}
|
|
819
726
|
}
|
|
@@ -821,305 +728,65 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
821
728
|
};
|
|
822
729
|
var handleMove = function handleMove(e) {
|
|
823
730
|
if (showResult || selectedPointIndex.current === null) return;
|
|
824
|
-
|
|
825
|
-
// ✅ FREE DRAG: Use delta-based movement for smooth, unconstrained dragging
|
|
826
|
-
|
|
827
731
|
var nativeEvent = e.nativeEvent;
|
|
828
732
|
var currentX = nativeEvent.locationX;
|
|
829
733
|
var currentY = nativeEvent.locationY;
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
console.warn("⚠️ Cannot get touch coordinates", {
|
|
834
|
-
locationX: nativeEvent.locationX,
|
|
835
|
-
locationY: nativeEvent.locationY
|
|
836
|
-
});
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// This is more reliable when ScrollView affects coordinate updates
|
|
841
|
-
var deltaX, deltaY;
|
|
734
|
+
if (currentX === undefined || currentY === undefined || isNaN(currentX) || isNaN(currentY)) return;
|
|
735
|
+
var deltaX = 0;
|
|
736
|
+
var deltaY = 0;
|
|
842
737
|
if (lastTouchPosition.current) {
|
|
843
|
-
// Calculate incremental delta from last touch position
|
|
844
738
|
deltaX = currentX - lastTouchPosition.current.x;
|
|
845
739
|
deltaY = currentY - lastTouchPosition.current.y;
|
|
846
740
|
} else if (initialTouchPosition.current) {
|
|
847
|
-
// Fallback to absolute delta if lastTouchPosition not set
|
|
848
741
|
deltaX = currentX - initialTouchPosition.current.x;
|
|
849
742
|
deltaY = currentY - initialTouchPosition.current.y;
|
|
850
|
-
} else {
|
|
851
|
-
console.warn("⚠️ No touch position reference available");
|
|
852
|
-
return;
|
|
853
743
|
}
|
|
854
|
-
|
|
855
|
-
// Les coordonnées de mouvement sont relatives au wrapper commun
|
|
856
744
|
var imageRect = imageDisplayRect.current;
|
|
857
745
|
var wrapper = commonWrapperLayout.current;
|
|
858
|
-
|
|
859
|
-
// Recalculate if not available
|
|
860
746
|
if (imageRect.width === 0 || imageRect.height === 0) {
|
|
861
747
|
if (wrapper.width > 0 && wrapper.height > 0 && originalImageDimensions.current.width > 0) {
|
|
862
748
|
updateImageDisplayRect(wrapper.width, wrapper.height);
|
|
863
749
|
imageRect = imageDisplayRect.current;
|
|
864
750
|
}
|
|
865
|
-
// If still not available, use full wrapper as fallback (wrapper-relative coords)
|
|
866
751
|
if (imageRect.width === 0 || imageRect.height === 0) {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
};
|
|
874
|
-
} else {
|
|
875
|
-
console.warn("⚠️ Cannot move point: wrapper or imageDisplayRect not available");
|
|
876
|
-
return;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
// ✅ Bounds in wrapper-relative coordinates (touch/points use wrapper as origin)
|
|
882
|
-
// Full picture = entire wrapper; visible image = imageDisplayRect
|
|
883
|
-
var contentRect = {
|
|
884
|
-
x: imageRect.x,
|
|
885
|
-
y: imageRect.y,
|
|
886
|
-
width: imageRect.width,
|
|
887
|
-
height: imageRect.height
|
|
888
|
-
};
|
|
889
|
-
|
|
890
|
-
// ✅ FREE DRAG: Ensure initial positions are set
|
|
891
|
-
if (!initialPointPosition.current) {
|
|
892
|
-
var currentPoint = points[selectedPointIndex.current];
|
|
893
|
-
if (currentPoint && typeof currentPoint.x === 'number' && typeof currentPoint.y === 'number') {
|
|
894
|
-
initialPointPosition.current = _objectSpread({}, currentPoint);
|
|
895
|
-
} else {
|
|
896
|
-
console.warn("⚠️ No point found for selected index or invalid point data");
|
|
897
|
-
return;
|
|
752
|
+
imageRect = {
|
|
753
|
+
x: 0,
|
|
754
|
+
y: 0,
|
|
755
|
+
width: wrapper.width || 0,
|
|
756
|
+
height: wrapper.height || 0
|
|
757
|
+
};
|
|
898
758
|
}
|
|
899
759
|
}
|
|
900
|
-
|
|
901
|
-
// ✅ NEW APPROACH: Use touchOffset to map touch position directly to point position
|
|
902
|
-
// This eliminates delta accumulation and "dead zone" issues completely
|
|
903
|
-
if (!touchOffset.current) {
|
|
904
|
-
console.warn("⚠️ touchOffset not initialized, cannot move point");
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
// ✅ DIRECT MAPPING: newPosition = touchPosition + offset
|
|
909
|
-
// No delta accumulation, no zone morte
|
|
910
|
-
var newX = currentX + touchOffset.current.x;
|
|
911
|
-
var newY = currentY + touchOffset.current.y;
|
|
912
|
-
|
|
913
|
-
// ✅ STRICT BOUNDS: visible image area (wrapper-relative) for lastValidPosition
|
|
914
|
-
var strictMinX = contentRect.x;
|
|
915
|
-
var strictMaxX = contentRect.x + contentRect.width;
|
|
916
|
-
var strictMinY = contentRect.y;
|
|
917
|
-
var strictMaxY = contentRect.y + contentRect.height;
|
|
918
|
-
|
|
919
|
-
// ✅ DRAG BOUNDS: keep points strictly on the visible picture (no going outside image)
|
|
920
|
-
var overshootMinX = strictMinX;
|
|
921
|
-
var overshootMaxX = strictMaxX;
|
|
922
|
-
var overshootMinY = strictMinY;
|
|
923
|
-
var overshootMaxY = strictMaxY;
|
|
924
|
-
|
|
925
|
-
// ✅ Clamp to visible image so points always stay on the picture
|
|
926
|
-
var dragX = Math.max(overshootMinX, Math.min(newX, overshootMaxX));
|
|
927
|
-
var dragY = Math.max(overshootMinY, Math.min(newY, overshootMaxY));
|
|
928
|
-
|
|
929
|
-
// ✅ UPDATE POINT: Use drag bounds (overshoot) - allows visual freedom
|
|
930
|
-
var updatedPoint = {
|
|
931
|
-
x: dragX,
|
|
932
|
-
y: dragY
|
|
933
|
-
};
|
|
934
|
-
|
|
935
|
-
// ✅ CRITICAL: Detect if point is AT overshoot boundary (not just clamped)
|
|
936
|
-
// Check if point is exactly at overshootMin/Max (within 1px tolerance)
|
|
937
|
-
var isAtOvershootMinX = Math.abs(dragX - overshootMinX) < 1;
|
|
938
|
-
var isAtOvershootMaxX = Math.abs(dragX - overshootMaxX) < 1;
|
|
939
|
-
var isAtOvershootMinY = Math.abs(dragY - overshootMinY) < 1;
|
|
940
|
-
var isAtOvershootMaxY = Math.abs(dragY - overshootMaxY) < 1;
|
|
941
|
-
var isAtBoundaryX = isAtOvershootMinX || isAtOvershootMaxX;
|
|
942
|
-
var isAtBoundaryY = isAtOvershootMinY || isAtOvershootMaxY;
|
|
943
|
-
|
|
944
|
-
// Only recalculate offset when FIRST hitting boundary (transition free → boundary)
|
|
945
|
-
var justHitBoundaryX = isAtBoundaryX && !wasClampedLastFrame.current.x;
|
|
946
|
-
var justHitBoundaryY = isAtBoundaryY && !wasClampedLastFrame.current.y;
|
|
947
|
-
if (justHitBoundaryX || justHitBoundaryY) {
|
|
948
|
-
// Point JUST hit overshoot boundary - recalculate offset once
|
|
949
|
-
var newOffsetX = justHitBoundaryX ? dragX - currentX : touchOffset.current.x;
|
|
950
|
-
var newOffsetY = justHitBoundaryY ? dragY - currentY : touchOffset.current.y;
|
|
951
|
-
touchOffset.current = {
|
|
952
|
-
x: newOffsetX,
|
|
953
|
-
y: newOffsetY
|
|
954
|
-
};
|
|
955
|
-
console.log("✅ OFFSET RECALCULATED (hit boundary):", {
|
|
956
|
-
axis: justHitBoundaryX ? 'X' : 'Y',
|
|
957
|
-
touchY: currentY.toFixed(2),
|
|
958
|
-
dragY: dragY.toFixed(2),
|
|
959
|
-
newOffsetY: touchOffset.current.y.toFixed(2),
|
|
960
|
-
note: "First contact with boundary - offset locked"
|
|
961
|
-
});
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
// Update boundary state for next frame
|
|
965
|
-
wasClampedLastFrame.current = {
|
|
966
|
-
x: isAtBoundaryX,
|
|
967
|
-
y: isAtBoundaryY
|
|
968
|
-
};
|
|
969
|
-
|
|
970
|
-
// ✅ DEBUG: Log when in overshoot zone (only when not at boundary)
|
|
971
|
-
var isInOvershootY = dragY < strictMinY || dragY > strictMaxY;
|
|
972
|
-
if (isInOvershootY && !isAtBoundaryY) {
|
|
973
|
-
console.log("🎯 IN OVERSHOOT ZONE:", {
|
|
974
|
-
touchY: currentY.toFixed(2),
|
|
975
|
-
appliedY: dragY.toFixed(2),
|
|
976
|
-
overshootRange: "".concat(overshootMinY.toFixed(2), " - ").concat(overshootMaxY.toFixed(2)),
|
|
977
|
-
strictRange: "".concat(strictMinY.toFixed(2), " - ").concat(strictMaxY.toFixed(2))
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// ✅ Update lastValidPosition ONLY if point is within strictBounds
|
|
982
|
-
var isStrictlyValid = dragX >= strictMinX && dragX <= strictMaxX && dragY >= strictMinY && dragY <= strictMaxY;
|
|
983
|
-
if (isStrictlyValid) {
|
|
984
|
-
lastValidPosition.current = updatedPoint;
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// ✅ Update lastTouchPosition for next frame (simple tracking)
|
|
988
760
|
lastTouchPosition.current = {
|
|
989
761
|
x: currentX,
|
|
990
762
|
y: currentY
|
|
991
763
|
};
|
|
992
|
-
|
|
993
|
-
// ✅ DEBUG: Log the point update before setPoints
|
|
994
|
-
console.log("📍 UPDATING POINT:", {
|
|
995
|
-
index: selectedPointIndex.current,
|
|
996
|
-
newX: updatedPoint.x.toFixed(2),
|
|
997
|
-
newY: updatedPoint.y.toFixed(2),
|
|
998
|
-
touchX: currentX.toFixed(2),
|
|
999
|
-
touchY: currentY.toFixed(2),
|
|
1000
|
-
offsetX: touchOffset.current.x.toFixed(2),
|
|
1001
|
-
offsetY: touchOffset.current.y.toFixed(2)
|
|
1002
|
-
});
|
|
1003
764
|
setPoints(function (prev) {
|
|
1004
|
-
|
|
1005
|
-
// ✅ SAFETY: Ensure prev is a valid array
|
|
1006
|
-
if (!Array.isArray(prev) || prev.length === 0) {
|
|
1007
|
-
return prev;
|
|
1008
|
-
}
|
|
765
|
+
if (!Array.isArray(prev) || prev.length === 0) return prev;
|
|
1009
766
|
var pointIndex = selectedPointIndex.current;
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
return
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
// ✅ SAFETY: Filter out any invalid points and update the selected one
|
|
1016
|
-
var newPoints = prev.map(function (p, i) {
|
|
1017
|
-
if (i === pointIndex) {
|
|
1018
|
-
return updatedPoint;
|
|
1019
|
-
}
|
|
1020
|
-
// ✅ SAFETY: Ensure existing points are valid
|
|
1021
|
-
if (p && typeof p.x === 'number' && typeof p.y === 'number') {
|
|
1022
|
-
return p;
|
|
1023
|
-
}
|
|
1024
|
-
// If point is invalid, return a default point (shouldn't happen, but safety first)
|
|
767
|
+
if (pointIndex === null || pointIndex < 0 || pointIndex >= prev.length) return prev;
|
|
768
|
+
return prev.map(function (p, i) {
|
|
769
|
+
if (i !== pointIndex) return p;
|
|
1025
770
|
return {
|
|
1026
|
-
x:
|
|
1027
|
-
y:
|
|
771
|
+
x: Math.max(imageRect.x, Math.min(p.x + deltaX, imageRect.x + imageRect.width)),
|
|
772
|
+
y: Math.max(imageRect.y, Math.min(p.y + deltaY, imageRect.y + imageRect.height))
|
|
1028
773
|
};
|
|
1029
774
|
});
|
|
1030
|
-
|
|
1031
|
-
// ✅ DEBUG: Log the state update
|
|
1032
|
-
console.log("✅ STATE UPDATED:", {
|
|
1033
|
-
index: pointIndex,
|
|
1034
|
-
oldY: (_prev$pointIndex = prev[pointIndex]) === null || _prev$pointIndex === void 0 ? void 0 : _prev$pointIndex.y.toFixed(2),
|
|
1035
|
-
newY: (_newPoints$pointIndex = newPoints[pointIndex]) === null || _newPoints$pointIndex === void 0 ? void 0 : _newPoints$pointIndex.y.toFixed(2),
|
|
1036
|
-
changed: Math.abs(((_prev$pointIndex2 = prev[pointIndex]) === null || _prev$pointIndex2 === void 0 ? void 0 : _prev$pointIndex2.y) - ((_newPoints$pointIndex2 = newPoints[pointIndex]) === null || _newPoints$pointIndex2 === void 0 ? void 0 : _newPoints$pointIndex2.y)) > 0.01
|
|
1037
|
-
});
|
|
1038
|
-
return newPoints;
|
|
1039
775
|
});
|
|
1040
776
|
};
|
|
1041
777
|
var handleRelease = function handleRelease() {
|
|
1042
778
|
var wasDragging = selectedPointIndex.current !== null;
|
|
1043
779
|
|
|
1044
|
-
// ✅
|
|
780
|
+
// ✅ FREE DRAG: Clear initial positions when drag ends
|
|
781
|
+
initialTouchPosition.current = null;
|
|
782
|
+
initialPointPosition.current = null;
|
|
783
|
+
lastTouchPosition.current = null;
|
|
784
|
+
lastValidPosition.current = null;
|
|
1045
785
|
touchOffset.current = null;
|
|
1046
786
|
wasClampedLastFrame.current = {
|
|
1047
787
|
x: false,
|
|
1048
788
|
y: false
|
|
1049
789
|
};
|
|
1050
|
-
|
|
1051
|
-
// ✅ VISUAL OVERSHOOT: Clamp points back to imageDisplayRect when drag ends
|
|
1052
|
-
// This ensures final crop is always within valid image bounds
|
|
1053
|
-
if (wasDragging && selectedPointIndex.current !== null) {
|
|
1054
|
-
var wrapper = commonWrapperLayout.current;
|
|
1055
|
-
var imageRect = imageDisplayRect.current;
|
|
1056
|
-
|
|
1057
|
-
// Recalculate imageDisplayRect if needed
|
|
1058
|
-
if (imageRect.width === 0 || imageRect.height === 0) {
|
|
1059
|
-
if (wrapper.width > 0 && wrapper.height > 0 && originalImageDimensions.current.width > 0) {
|
|
1060
|
-
updateImageDisplayRect(wrapper.width, wrapper.height);
|
|
1061
|
-
imageRect = imageDisplayRect.current;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
if (imageRect.width > 0 && imageRect.height > 0) {
|
|
1065
|
-
// Bounds in wrapper-relative coords (same as point coords)
|
|
1066
|
-
var minX = imageRect.x;
|
|
1067
|
-
var minY = imageRect.y;
|
|
1068
|
-
var maxX = imageRect.x + imageRect.width;
|
|
1069
|
-
var maxY = imageRect.y + imageRect.height;
|
|
1070
|
-
|
|
1071
|
-
// Clamp the dragged point back to visible image area (full picture in wrapper-relative coords)
|
|
1072
|
-
setPoints(function (prev) {
|
|
1073
|
-
// ✅ SAFETY: Ensure prev is a valid array
|
|
1074
|
-
if (!Array.isArray(prev) || prev.length === 0) {
|
|
1075
|
-
return prev;
|
|
1076
|
-
}
|
|
1077
|
-
var pointIndex = selectedPointIndex.current;
|
|
1078
|
-
// ✅ SAFETY: Validate pointIndex and ensure point exists
|
|
1079
|
-
if (pointIndex === null || pointIndex === undefined || pointIndex < 0 || pointIndex >= prev.length) {
|
|
1080
|
-
return prev;
|
|
1081
|
-
}
|
|
1082
|
-
var point = prev[pointIndex];
|
|
1083
|
-
// ✅ SAFETY: Ensure point exists and has valid x/y properties
|
|
1084
|
-
if (!point || typeof point.x !== 'number' || typeof point.y !== 'number') {
|
|
1085
|
-
return prev;
|
|
1086
|
-
}
|
|
1087
|
-
var clampedPoint = {
|
|
1088
|
-
x: Math.max(minX, Math.min(point.x, maxX)),
|
|
1089
|
-
y: Math.max(minY, Math.min(point.y, maxY))
|
|
1090
|
-
};
|
|
1091
|
-
|
|
1092
|
-
// Only update if point was outside bounds
|
|
1093
|
-
if (point.x !== clampedPoint.x || point.y !== clampedPoint.y) {
|
|
1094
|
-
console.log("🔒 Clamping point back to image bounds on release:", {
|
|
1095
|
-
before: {
|
|
1096
|
-
x: point.x.toFixed(2),
|
|
1097
|
-
y: point.y.toFixed(2)
|
|
1098
|
-
},
|
|
1099
|
-
after: {
|
|
1100
|
-
x: clampedPoint.x.toFixed(2),
|
|
1101
|
-
y: clampedPoint.y.toFixed(2)
|
|
1102
|
-
},
|
|
1103
|
-
bounds: {
|
|
1104
|
-
minX: minX.toFixed(2),
|
|
1105
|
-
maxX: maxX.toFixed(2),
|
|
1106
|
-
minY: minY.toFixed(2),
|
|
1107
|
-
maxY: maxY.toFixed(2)
|
|
1108
|
-
}
|
|
1109
|
-
});
|
|
1110
|
-
return prev.map(function (p, i) {
|
|
1111
|
-
return i === pointIndex ? clampedPoint : p;
|
|
1112
|
-
});
|
|
1113
|
-
}
|
|
1114
|
-
return prev;
|
|
1115
|
-
});
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
// ✅ FREE DRAG: Clear initial positions when drag ends
|
|
1120
|
-
initialTouchPosition.current = null;
|
|
1121
|
-
initialPointPosition.current = null;
|
|
1122
|
-
lastValidPosition.current = null;
|
|
1123
790
|
selectedPointIndex.current = null;
|
|
1124
791
|
|
|
1125
792
|
// ✅ CRITICAL: Re-enable parent ScrollView scrolling when drag ends
|
|
@@ -1227,6 +894,21 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1227
894
|
setImmediate(_tick);
|
|
1228
895
|
});
|
|
1229
896
|
};
|
|
897
|
+
var getFrameBounds = function getFrameBounds() {
|
|
898
|
+
if (!points || points.length < 4) return null;
|
|
899
|
+
var xs = points.map(function (p) {
|
|
900
|
+
return p.x;
|
|
901
|
+
});
|
|
902
|
+
var ys = points.map(function (p) {
|
|
903
|
+
return p.y;
|
|
904
|
+
});
|
|
905
|
+
return {
|
|
906
|
+
minX: Math.min.apply(Math, _toConsumableArray(xs)),
|
|
907
|
+
maxX: Math.max.apply(Math, _toConsumableArray(xs)),
|
|
908
|
+
minY: Math.min.apply(Math, _toConsumableArray(ys)),
|
|
909
|
+
maxY: Math.max.apply(Math, _toConsumableArray(ys))
|
|
910
|
+
};
|
|
911
|
+
};
|
|
1230
912
|
return /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1231
913
|
style: _ImageCropperStyles["default"].container
|
|
1232
914
|
}, showCustomCamera ? /*#__PURE__*/_react["default"].createElement(_CustomCamera["default"], {
|
|
@@ -1350,7 +1032,7 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1350
1032
|
var sizeScale = Math.max(0.6, Math.min(1.4, sizeScaleRaw)); // clamp
|
|
1351
1033
|
|
|
1352
1034
|
var stroke = Math.max(0.75, 2 * responsiveScale * sizeScale);
|
|
1353
|
-
var handleRadius = Math.max(
|
|
1035
|
+
var handleRadius = Math.max(5, 9 * responsiveScale * sizeScale);
|
|
1354
1036
|
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Path, {
|
|
1355
1037
|
d: "M 0 0 H ".concat(wrapperWidth, " V ").concat(wrapperHeight, " H 0 Z ").concat(createPath()),
|
|
1356
1038
|
fill: showResult ? 'white' : 'rgba(0, 0, 0, 0.8)',
|
|
@@ -1358,18 +1040,20 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1358
1040
|
}), !showResult && points.length > 0 && /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Path, {
|
|
1359
1041
|
d: createPath(),
|
|
1360
1042
|
fill: "transparent",
|
|
1361
|
-
stroke: "
|
|
1043
|
+
stroke: "rgba(255,255,255,0.95)",
|
|
1362
1044
|
strokeWidth: stroke
|
|
1363
1045
|
}), !showResult && points.map(function (point, index) {
|
|
1364
1046
|
return /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Circle, {
|
|
1365
|
-
key: index,
|
|
1047
|
+
key: "dot-".concat(index),
|
|
1366
1048
|
cx: point.x,
|
|
1367
1049
|
cy: point.y,
|
|
1368
1050
|
r: handleRadius,
|
|
1369
|
-
fill: "
|
|
1051
|
+
fill: "#E7FFD9",
|
|
1052
|
+
stroke: ACCENT_GREEN,
|
|
1053
|
+
strokeWidth: 1.5
|
|
1370
1054
|
});
|
|
1371
1055
|
}));
|
|
1372
|
-
}())), isRotating && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1056
|
+
}()), !showResult && image && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null)), isRotating && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1373
1057
|
style: {
|
|
1374
1058
|
position: 'absolute',
|
|
1375
1059
|
left: 0,
|
|
@@ -1391,61 +1075,72 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1391
1075
|
}
|
|
1392
1076
|
}, rotationLabel !== null && rotationLabel !== void 0 ? rotationLabel : 'Rotation...')))), !showResult && image && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1393
1077
|
style: [_ImageCropperStyles["default"].buttonContainerBelow, {
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1078
|
+
// Keep controls clearly above home indicator / bottom gesture bar.
|
|
1079
|
+
paddingBottom: Math.max(insets.bottom + Math.round(12 * responsiveScale), Math.round(20 * responsiveScale)),
|
|
1080
|
+
paddingTop: Math.round(10 * responsiveScale),
|
|
1081
|
+
paddingHorizontal: Math.round(12 * responsiveScale)
|
|
1398
1082
|
}]
|
|
1083
|
+
}, /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1084
|
+
style: _ImageCropperStyles["default"].controlsRow
|
|
1399
1085
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
|
|
1400
|
-
style: [_ImageCropperStyles["default"].
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
width: Math.round(40 * responsiveScale),
|
|
1405
|
-
height: Math.round(40 * responsiveScale),
|
|
1406
|
-
borderRadius: Math.round(20 * responsiveScale),
|
|
1407
|
-
marginRight: Math.round(6 * responsiveScale)
|
|
1086
|
+
style: [_ImageCropperStyles["default"].roundControl, {
|
|
1087
|
+
width: 'auto',
|
|
1088
|
+
minWidth: Math.max(Math.round(84 * responsiveScale), Math.round(((cancelText ? String(cancelText).length : 6) * 7 + 32) * responsiveScale)),
|
|
1089
|
+
paddingHorizontal: Math.round(12 * responsiveScale)
|
|
1408
1090
|
}],
|
|
1409
1091
|
onPress: function onPress() {
|
|
1410
1092
|
if (onCancel) {
|
|
1411
1093
|
onCancel();
|
|
1412
1094
|
}
|
|
1413
|
-
}
|
|
1095
|
+
},
|
|
1096
|
+
activeOpacity: 0.85
|
|
1097
|
+
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1098
|
+
style: [_ImageCropperStyles["default"].buttonText, {
|
|
1099
|
+
fontSize: Math.max(10, Math.round(11 * responsiveScale)),
|
|
1100
|
+
letterSpacing: 0.5
|
|
1101
|
+
}]
|
|
1102
|
+
}, cancelText)), /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
|
|
1103
|
+
style: _ImageCropperStyles["default"].enhanceButton,
|
|
1104
|
+
onPress: handleReset,
|
|
1105
|
+
activeOpacity: 0.85
|
|
1414
1106
|
}, /*#__PURE__*/_react["default"].createElement(_vectorIcons.Ionicons, {
|
|
1415
|
-
name: "
|
|
1416
|
-
size: Math.round(
|
|
1417
|
-
color: "
|
|
1418
|
-
})
|
|
1107
|
+
name: "sparkles-outline",
|
|
1108
|
+
size: Math.round(18 * responsiveScale),
|
|
1109
|
+
color: "rgba(255,255,255,0.95)"
|
|
1110
|
+
}), /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1111
|
+
style: _ImageCropperStyles["default"].buttonText,
|
|
1112
|
+
numberOfLines: 1,
|
|
1113
|
+
ellipsizeMode: "tail"
|
|
1114
|
+
}, resetText || 'Enhance')), /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
|
|
1419
1115
|
style: [_ImageCropperStyles["default"].rotationButton, {
|
|
1420
|
-
|
|
1421
|
-
height: Math.round(48 * responsiveScale),
|
|
1422
|
-
borderRadius: Math.round(28 * responsiveScale)
|
|
1116
|
+
minWidth: Math.max(Math.round(88 * responsiveScale), Math.round(((rotateText ? String(rotateText).length : 6) * 7 + 38) * responsiveScale))
|
|
1423
1117
|
}, isRotating && {
|
|
1424
1118
|
opacity: 0.7
|
|
1425
1119
|
}],
|
|
1426
1120
|
onPress: function onPress() {
|
|
1427
1121
|
return enableRotation && rotatePreviewImage(90);
|
|
1428
1122
|
},
|
|
1429
|
-
disabled: isRotating
|
|
1123
|
+
disabled: isRotating,
|
|
1124
|
+
activeOpacity: 0.85
|
|
1430
1125
|
}, isRotating ? /*#__PURE__*/_react["default"].createElement(_reactNative.ActivityIndicator, {
|
|
1431
1126
|
size: "small",
|
|
1432
1127
|
color: "white"
|
|
1433
|
-
}) : /*#__PURE__*/_react["default"].createElement(
|
|
1434
|
-
|
|
1435
|
-
|
|
1128
|
+
}) : /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1129
|
+
style: {
|
|
1130
|
+
flexDirection: 'row',
|
|
1131
|
+
alignItems: 'center',
|
|
1132
|
+
gap: 6
|
|
1133
|
+
}
|
|
1134
|
+
}, /*#__PURE__*/_react["default"].createElement(_vectorIcons.Ionicons, {
|
|
1135
|
+
name: "refresh",
|
|
1136
|
+
size: Math.round(15 * responsiveScale),
|
|
1436
1137
|
color: "white"
|
|
1437
|
-
})
|
|
1438
|
-
style: [_ImageCropperStyles["default"].button, {
|
|
1439
|
-
minHeight: Math.round(48 * responsiveScale),
|
|
1440
|
-
paddingVertical: Math.round(12 * responsiveScale),
|
|
1441
|
-
paddingHorizontal: Math.round(10 * responsiveScale)
|
|
1442
|
-
}],
|
|
1443
|
-
onPress: handleReset
|
|
1444
|
-
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1138
|
+
}), /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1445
1139
|
style: [_ImageCropperStyles["default"].buttonText, {
|
|
1446
|
-
fontSize: Math.max(
|
|
1140
|
+
fontSize: Math.max(10, Math.round(11 * responsiveScale)),
|
|
1141
|
+
letterSpacing: 0.5
|
|
1447
1142
|
}]
|
|
1448
|
-
},
|
|
1143
|
+
}, rotateText)))), /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
|
|
1449
1144
|
onPress: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
1450
1145
|
var _cameraFrameData$curr4, actualImageWidth, actualImageHeight, isCoverMode, captured, layout, contentRect, displayedWidth, displayedHeight, scale, coverOffsetX, coverOffsetY, scaledWidth, scaledHeight, originalUri, cropMeta, imagePoints, minX, minY, maxX, maxY, cropX, cropY, cropEndX, cropEndY, cropWidth, cropHeight, bbox, polygon, ext, safeExt, name, _t2;
|
|
1451
1146
|
return _regenerator().w(function (_context2) {
|
|
@@ -1613,15 +1308,25 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1613
1308
|
}, _callee2, null, [[1, 5, 6, 7]]);
|
|
1614
1309
|
})),
|
|
1615
1310
|
style: [_ImageCropperStyles["default"].button, {
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1311
|
+
marginTop: Math.round(10 * responsiveScale),
|
|
1312
|
+
// Keep confirm action above browser/system navigation bars.
|
|
1313
|
+
marginBottom: Math.max(insets.bottom + Math.round(10 * responsiveScale), Math.round(22 * responsiveScale)),
|
|
1314
|
+
borderWidth: 1.8,
|
|
1315
|
+
borderColor: ACCENT_GREEN
|
|
1316
|
+
}],
|
|
1317
|
+
hitSlop: {
|
|
1318
|
+
top: 8,
|
|
1319
|
+
left: 8,
|
|
1320
|
+
right: 8,
|
|
1321
|
+
bottom: 12
|
|
1322
|
+
}
|
|
1620
1323
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1621
1324
|
style: [_ImageCropperStyles["default"].buttonText, {
|
|
1622
|
-
fontSize: Math.max(
|
|
1623
|
-
}]
|
|
1624
|
-
|
|
1325
|
+
fontSize: Math.max(13, Math.round(14 * responsiveScale))
|
|
1326
|
+
}],
|
|
1327
|
+
numberOfLines: 1,
|
|
1328
|
+
ellipsizeMode: "tail"
|
|
1329
|
+
}, confirmText || 'Use Scan'))), !showResult && !image && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1625
1330
|
style: _ImageCropperStyles["default"].centerButtonsContainer
|
|
1626
1331
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1627
1332
|
style: _ImageCropperStyles["default"].welcomeText
|