react-native-expo-cropper 1.2.36 → 1.2.37
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/babel.config.js +6 -0
- package/dist/CustomCamera.js +343 -245
- package/dist/ImageCropper.js +1620 -513
- package/dist/ImageCropperStyles.js +217 -217
- package/dist/ImageMaskProcessor.js +177 -0
- package/dist/ImageProcessor.js +40 -52
- package/package.json +5 -5
- package/src/CustomCamera.js +93 -18
- package/src/ImageCropper.js +861 -58
package/dist/ImageProcessor.js
CHANGED
|
@@ -1,53 +1,41 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.enhanceImage = void 0;
|
|
8
|
-
var ImageManipulator = _interopRequireWildcard(require("expo-image-manipulator"));
|
|
9
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
|
|
10
|
-
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
11
|
-
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
12
|
-
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
13
|
-
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
_context.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return _context.a(2, result.uri);
|
|
42
|
-
case 3:
|
|
43
|
-
_context.p = 3;
|
|
44
|
-
_t = _context.v;
|
|
45
|
-
console.error("Erreur T404K:", _t);
|
|
46
|
-
return _context.a(2, uri);
|
|
47
|
-
}
|
|
48
|
-
}, _callee, null, [[0, 3]]);
|
|
49
|
-
}));
|
|
50
|
-
return function enhanceImage(_x, _x2) {
|
|
51
|
-
return _ref.apply(this, arguments);
|
|
52
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.enhanceImage = void 0;
|
|
8
|
+
var ImageManipulator = _interopRequireWildcard(require("expo-image-manipulator"));
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
|
|
10
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
11
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
12
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
13
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
14
|
+
/**
|
|
15
|
+
* Retourne l'image originale sans redimensionnement pour préserver la qualité maximale.
|
|
16
|
+
* Le redimensionnement destructif a été supprimé pour éviter la perte de résolution.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} uri - URI de l'image originale
|
|
19
|
+
* @param {number} addheight - Paramètre conservé pour compatibilité (non utilisé)
|
|
20
|
+
* @returns {Promise<string>} URI de l'image originale (sans modification)
|
|
21
|
+
*/
|
|
22
|
+
var enhanceImage = exports.enhanceImage = /*#__PURE__*/function () {
|
|
23
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(uri, addheight) {
|
|
24
|
+
var _t;
|
|
25
|
+
return _regenerator().w(function (_context) {
|
|
26
|
+
while (1) switch (_context.p = _context.n) {
|
|
27
|
+
case 0:
|
|
28
|
+
_context.p = 0;
|
|
29
|
+
return _context.a(2, uri);
|
|
30
|
+
case 1:
|
|
31
|
+
_context.p = 1;
|
|
32
|
+
_t = _context.v;
|
|
33
|
+
console.error("Erreur enhanceImage:", _t);
|
|
34
|
+
return _context.a(2, uri);
|
|
35
|
+
}
|
|
36
|
+
}, _callee, null, [[0, 1]]);
|
|
37
|
+
}));
|
|
38
|
+
return function enhanceImage(_x, _x2) {
|
|
39
|
+
return _ref.apply(this, arguments);
|
|
40
|
+
};
|
|
53
41
|
}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-expo-cropper",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.37",
|
|
4
4
|
"description": "Recadrage polygonal d'images.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "PCS AGRI",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"url": "https://github.com/pcsagri/react-native-expo-cropper/issues"
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://github.com/pcsagri/react-native-expo-cropper#readme",
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
"scripts": {
|
|
49
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
50
|
+
"build": "npx --package=@babel/cli babel src --out-dir dist"
|
|
51
|
+
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@babel/cli": "^7.28.3",
|
|
54
54
|
"@babel/core": "^7.28.5",
|
package/src/CustomCamera.js
CHANGED
|
@@ -13,23 +13,22 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
13
13
|
import { Camera, CameraView } from 'expo-camera';
|
|
14
14
|
const { width } = Dimensions.get('window');
|
|
15
15
|
|
|
16
|
-
export default function CustomCamera({ onPhotoCaptured}) {
|
|
16
|
+
export default function CustomCamera({ onPhotoCaptured, onFrameCalculated }) {
|
|
17
17
|
const [isReady, setIsReady] = useState(false);
|
|
18
18
|
const [loadingBeforeCapture, setLoadingBeforeCapture] = useState(false);
|
|
19
19
|
const [hasPermission, setHasPermission] = useState(null);
|
|
20
20
|
const cameraRef = useRef(null);
|
|
21
|
+
const cameraWrapperRef = useRef(null);
|
|
21
22
|
const insets = useSafeAreaInsets();
|
|
23
|
+
const [cameraWrapperLayout, setCameraWrapperLayout] = useState({ width: 0, height: 0, x: 0, y: 0 });
|
|
24
|
+
const [greenFrame, setGreenFrame] = useState(null);
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
})();
|
|
30
|
-
}, []);
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
(async () => {
|
|
28
|
+
const { status } = await Camera.requestCameraPermissionsAsync();
|
|
29
|
+
setHasPermission(status === 'granted');
|
|
30
|
+
})();
|
|
31
|
+
}, []);
|
|
33
32
|
|
|
34
33
|
// Helper function to wait for multiple render cycles (works on iOS)
|
|
35
34
|
const waitForRender = (cycles = 5) => {
|
|
@@ -49,6 +48,52 @@ useEffect(() => {
|
|
|
49
48
|
|
|
50
49
|
|
|
51
50
|
|
|
51
|
+
// ✅ CRITICAL FIX: Calculate green frame coordinates relative to camera preview
|
|
52
|
+
// The green frame should be calculated on the wrapper (as it's visually drawn there)
|
|
53
|
+
// But we store it with wrapper dimensions so ImageCropper can map it correctly
|
|
54
|
+
const calculateGreenFrameCoordinates = () => {
|
|
55
|
+
const wrapperWidth = cameraWrapperLayout.width;
|
|
56
|
+
const wrapperHeight = cameraWrapperLayout.height;
|
|
57
|
+
|
|
58
|
+
if (wrapperWidth === 0 || wrapperHeight === 0) {
|
|
59
|
+
console.warn("Camera wrapper layout not ready, cannot calculate green frame");
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ✅ Green frame dimensions: 80% width, 80% height (centered)
|
|
64
|
+
// The green frame should cover 80% of the image area, centered
|
|
65
|
+
const frameWidth = wrapperWidth * 0.80; // 80% width
|
|
66
|
+
const frameHeight = wrapperHeight * 0.80; // 80% height
|
|
67
|
+
const frameX = (wrapperWidth - frameWidth) / 2; // Centered horizontally
|
|
68
|
+
const frameY = (wrapperHeight - frameHeight) / 2; // Centered vertically
|
|
69
|
+
|
|
70
|
+
const frameCoords = {
|
|
71
|
+
x: frameX,
|
|
72
|
+
y: frameY,
|
|
73
|
+
width: frameWidth,
|
|
74
|
+
height: frameHeight,
|
|
75
|
+
wrapperWidth,
|
|
76
|
+
wrapperHeight,
|
|
77
|
+
// ✅ Store percentages for easier mapping later
|
|
78
|
+
percentX: (frameX / wrapperWidth) * 100,
|
|
79
|
+
percentY: (frameY / wrapperHeight) * 100,
|
|
80
|
+
percentWidth: 80,
|
|
81
|
+
percentHeight: 80
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
console.log("✅ Green frame coordinates calculated:", frameCoords);
|
|
85
|
+
return frameCoords;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// 🔁 Keep green frame state in sync with wrapper layout so we can both render it
|
|
89
|
+
// and send the exact same coordinates along with the captured photo.
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
const coords = calculateGreenFrameCoordinates();
|
|
92
|
+
if (coords) {
|
|
93
|
+
setGreenFrame(coords);
|
|
94
|
+
}
|
|
95
|
+
}, [cameraWrapperLayout]);
|
|
96
|
+
|
|
52
97
|
const takePicture = async () => {
|
|
53
98
|
if (cameraRef.current) {
|
|
54
99
|
try {
|
|
@@ -79,14 +124,21 @@ useEffect(() => {
|
|
|
79
124
|
exif: photo.exif ? "present" : "missing"
|
|
80
125
|
});
|
|
81
126
|
|
|
127
|
+
// ✅ CRITICAL FIX: Use the same green frame coordinates that are used for rendering
|
|
128
|
+
// Fallback to recalculation if, for some reason, state is not yet set
|
|
129
|
+
const greenFrameCoords = greenFrame || calculateGreenFrameCoordinates();
|
|
130
|
+
|
|
82
131
|
// ✅ REFACTORISATION : Utiliser directement l'URI de la photo
|
|
83
132
|
// L'orientation sera gérée dans ImageCropper si l'utilisateur utilise la fonction de rotation
|
|
84
133
|
// skipProcessing: true préserve la qualité mais peut laisser l'orientation EXIF non appliquée
|
|
85
134
|
// C'est acceptable car l'utilisateur peut corriger via la rotation dans ImageCropper
|
|
86
135
|
const fixedUri = photo.uri;
|
|
87
136
|
|
|
88
|
-
// Envoyer
|
|
89
|
-
onPhotoCaptured(fixedUri
|
|
137
|
+
// Envoyer l'URI et les coordonnées du green frame à ImageCropper
|
|
138
|
+
onPhotoCaptured(fixedUri, {
|
|
139
|
+
greenFrame: greenFrameCoords,
|
|
140
|
+
capturedImageSize: { width: photo.width, height: photo.height }
|
|
141
|
+
});
|
|
90
142
|
setLoadingBeforeCapture(false);
|
|
91
143
|
} catch (error) {
|
|
92
144
|
console.error("Error capturing photo:", error);
|
|
@@ -99,7 +151,20 @@ useEffect(() => {
|
|
|
99
151
|
|
|
100
152
|
return (
|
|
101
153
|
<SafeAreaView style={styles.outerContainer}>
|
|
102
|
-
<View
|
|
154
|
+
<View
|
|
155
|
+
style={styles.cameraWrapper}
|
|
156
|
+
ref={cameraWrapperRef}
|
|
157
|
+
onLayout={(e) => {
|
|
158
|
+
const layout = e.nativeEvent.layout;
|
|
159
|
+
setCameraWrapperLayout({
|
|
160
|
+
width: layout.width,
|
|
161
|
+
height: layout.height,
|
|
162
|
+
x: layout.x,
|
|
163
|
+
y: layout.y
|
|
164
|
+
});
|
|
165
|
+
console.log("Camera wrapper layout updated:", layout);
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
103
168
|
<CameraView
|
|
104
169
|
style={styles.camera}
|
|
105
170
|
facing="back"
|
|
@@ -121,8 +186,20 @@ useEffect(() => {
|
|
|
121
186
|
</>
|
|
122
187
|
)}
|
|
123
188
|
|
|
124
|
-
{/* Cadre de scan */}
|
|
125
|
-
|
|
189
|
+
{/* Cadre de scan - rendered using calculated coordinates (x, y, width, height) */}
|
|
190
|
+
{greenFrame && (
|
|
191
|
+
<View
|
|
192
|
+
style={[
|
|
193
|
+
styles.scanFrame,
|
|
194
|
+
{
|
|
195
|
+
left: greenFrame.x,
|
|
196
|
+
top: greenFrame.y,
|
|
197
|
+
width: greenFrame.width,
|
|
198
|
+
height: greenFrame.height,
|
|
199
|
+
},
|
|
200
|
+
]}
|
|
201
|
+
/>
|
|
202
|
+
)}
|
|
126
203
|
</View>
|
|
127
204
|
|
|
128
205
|
<View style={[styles.buttonContainer, { bottom: (insets?.bottom || 0) + 16, marginBottom: 0 }]}>
|
|
@@ -161,8 +238,6 @@ const styles = StyleSheet.create({
|
|
|
161
238
|
},
|
|
162
239
|
scanFrame: {
|
|
163
240
|
position: 'absolute',
|
|
164
|
-
width: '95%',
|
|
165
|
-
height: '80%',
|
|
166
241
|
borderWidth: 4,
|
|
167
242
|
borderColor: PRIMARY_GREEN,
|
|
168
243
|
borderRadius: 5,
|