react-native-expo-cropper 1.2.52 → 1.2.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/ImageCropper.js +22 -6
- package/package.json +1 -1
- package/src/ImageCropper.js +37 -5
package/dist/ImageCropper.js
CHANGED
|
@@ -913,8 +913,10 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
913
913
|
// ✅ STRICT BOUNDS: visible image area (wrapper-relative) for lastValidPosition
|
|
914
914
|
var strictMinX = contentRect.x;
|
|
915
915
|
var strictMaxX = contentRect.x + contentRect.width;
|
|
916
|
+
// Tiny safety margin at bottom (2px) so point can almost reach bottom edge
|
|
917
|
+
var bottomSafePadding = 2;
|
|
916
918
|
var strictMinY = contentRect.y;
|
|
917
|
-
var strictMaxY = contentRect.y + contentRect.height;
|
|
919
|
+
var strictMaxY = contentRect.y + contentRect.height - bottomSafePadding;
|
|
918
920
|
|
|
919
921
|
// ✅ DRAG BOUNDS: keep points strictly on the visible picture (no going outside image)
|
|
920
922
|
var overshootMinX = strictMinX;
|
|
@@ -926,7 +928,15 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
926
928
|
var dragX = Math.max(overshootMinX, Math.min(newX, overshootMaxX));
|
|
927
929
|
var dragY = Math.max(overshootMinY, Math.min(newY, overshootMaxY));
|
|
928
930
|
|
|
929
|
-
// ✅
|
|
931
|
+
// ✅ Bottom-band "stickiness": if the point is already in the last few pixels
|
|
932
|
+
// near the bottom, ignore any move that would suddenly pull it back up.
|
|
933
|
+
var bottomBandThreshold = strictMaxY - 3; // last ~3px of allowed area
|
|
934
|
+
var prevPoint = points[selectedPointIndex.current];
|
|
935
|
+
if (prevPoint && prevPoint.y >= bottomBandThreshold && dragY < prevPoint.y) {
|
|
936
|
+
dragY = prevPoint.y;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// ✅ UPDATE POINT: Use (possibly adjusted) dragY
|
|
930
940
|
var updatedPoint = {
|
|
931
941
|
x: dragX,
|
|
932
942
|
y: dragY
|
|
@@ -1443,8 +1453,11 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1443
1453
|
onPress: handleReset
|
|
1444
1454
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1445
1455
|
style: [_ImageCropperStyles["default"].buttonText, {
|
|
1446
|
-
|
|
1447
|
-
|
|
1456
|
+
// Smaller font for longer labels so they stay on one line
|
|
1457
|
+
fontSize: Math.max(12, Math.round((resetText && resetText.length > 10 ? 14 : 18) * responsiveScale))
|
|
1458
|
+
}],
|
|
1459
|
+
numberOfLines: 1,
|
|
1460
|
+
ellipsizeMode: "tail"
|
|
1448
1461
|
}, resetText)), /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
|
|
1449
1462
|
onPress: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
1450
1463
|
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;
|
|
@@ -1619,8 +1632,11 @@ var ImageCropper = function ImageCropper(_ref) {
|
|
|
1619
1632
|
}]
|
|
1620
1633
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
|
1621
1634
|
style: [_ImageCropperStyles["default"].buttonText, {
|
|
1622
|
-
|
|
1623
|
-
|
|
1635
|
+
// Smaller font for longer labels so they stay on one line
|
|
1636
|
+
fontSize: Math.max(12, Math.round((confirmText && confirmText.length > 10 ? 14 : 18) * responsiveScale))
|
|
1637
|
+
}],
|
|
1638
|
+
numberOfLines: 1,
|
|
1639
|
+
ellipsizeMode: "tail"
|
|
1624
1640
|
}, confirmText))), !showResult && !image && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
|
|
1625
1641
|
style: _ImageCropperStyles["default"].centerButtonsContainer
|
|
1626
1642
|
}, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
|
package/package.json
CHANGED
package/src/ImageCropper.js
CHANGED
|
@@ -773,8 +773,10 @@ const ImageCropper = ({
|
|
|
773
773
|
// ✅ STRICT BOUNDS: visible image area (wrapper-relative) for lastValidPosition
|
|
774
774
|
const strictMinX = contentRect.x;
|
|
775
775
|
const strictMaxX = contentRect.x + contentRect.width;
|
|
776
|
+
// Tiny safety margin at bottom (2px) so point can almost reach bottom edge
|
|
777
|
+
const bottomSafePadding = 2;
|
|
776
778
|
const strictMinY = contentRect.y;
|
|
777
|
-
const strictMaxY = contentRect.y + contentRect.height;
|
|
779
|
+
const strictMaxY = contentRect.y + contentRect.height - bottomSafePadding;
|
|
778
780
|
|
|
779
781
|
// ✅ DRAG BOUNDS: keep points strictly on the visible picture (no going outside image)
|
|
780
782
|
const overshootMinX = strictMinX;
|
|
@@ -784,9 +786,17 @@ const ImageCropper = ({
|
|
|
784
786
|
|
|
785
787
|
// ✅ Clamp to visible image so points always stay on the picture
|
|
786
788
|
const dragX = Math.max(overshootMinX, Math.min(newX, overshootMaxX));
|
|
787
|
-
|
|
789
|
+
let dragY = Math.max(overshootMinY, Math.min(newY, overshootMaxY));
|
|
788
790
|
|
|
789
|
-
// ✅
|
|
791
|
+
// ✅ Bottom-band "stickiness": if the point is already in the last few pixels
|
|
792
|
+
// near the bottom, ignore any move that would suddenly pull it back up.
|
|
793
|
+
const bottomBandThreshold = strictMaxY - 3; // last ~3px of allowed area
|
|
794
|
+
const prevPoint = points[selectedPointIndex.current];
|
|
795
|
+
if (prevPoint && prevPoint.y >= bottomBandThreshold && dragY < prevPoint.y) {
|
|
796
|
+
dragY = prevPoint.y;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// ✅ UPDATE POINT: Use (possibly adjusted) dragY
|
|
790
800
|
const updatedPoint = { x: dragX, y: dragY };
|
|
791
801
|
|
|
792
802
|
// ✅ CRITICAL: Detect if point is AT overshoot boundary (not just clamped)
|
|
@@ -1273,8 +1283,19 @@ const rotatePreviewImage = async (degrees) => {
|
|
|
1273
1283
|
<Text
|
|
1274
1284
|
style={[
|
|
1275
1285
|
styles.buttonText,
|
|
1276
|
-
{
|
|
1286
|
+
{
|
|
1287
|
+
// Smaller font for longer labels so they stay on one line
|
|
1288
|
+
fontSize: Math.max(
|
|
1289
|
+
12,
|
|
1290
|
+
Math.round(
|
|
1291
|
+
(resetText && resetText.length > 10 ? 14 : 18) *
|
|
1292
|
+
responsiveScale
|
|
1293
|
+
)
|
|
1294
|
+
),
|
|
1295
|
+
},
|
|
1277
1296
|
]}
|
|
1297
|
+
numberOfLines={1}
|
|
1298
|
+
ellipsizeMode="tail"
|
|
1278
1299
|
>
|
|
1279
1300
|
{resetText}
|
|
1280
1301
|
</Text>
|
|
@@ -1423,8 +1444,19 @@ const rotatePreviewImage = async (degrees) => {
|
|
|
1423
1444
|
<Text
|
|
1424
1445
|
style={[
|
|
1425
1446
|
styles.buttonText,
|
|
1426
|
-
{
|
|
1447
|
+
{
|
|
1448
|
+
// Smaller font for longer labels so they stay on one line
|
|
1449
|
+
fontSize: Math.max(
|
|
1450
|
+
12,
|
|
1451
|
+
Math.round(
|
|
1452
|
+
(confirmText && confirmText.length > 10 ? 14 : 18) *
|
|
1453
|
+
responsiveScale
|
|
1454
|
+
)
|
|
1455
|
+
),
|
|
1456
|
+
},
|
|
1427
1457
|
]}
|
|
1458
|
+
numberOfLines={1}
|
|
1459
|
+
ellipsizeMode="tail"
|
|
1428
1460
|
>
|
|
1429
1461
|
{confirmText}
|
|
1430
1462
|
</Text>
|