@buoy-gg/image-overlay 7.0.40 → 7.0.42

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.
Files changed (42) hide show
  1. package/README.md +12 -72
  2. package/lib/commonjs/imageOverlay/components/ImageOverlayModal.js +1 -875
  3. package/lib/commonjs/imageOverlay/components/ImageOverlayStandalone.js +1 -456
  4. package/lib/commonjs/imageOverlay/components/OverlayControls.js +1 -253
  5. package/lib/commonjs/imageOverlay/components/TargetList.js +1 -181
  6. package/lib/commonjs/imageOverlay/types/index.js +1 -1
  7. package/lib/commonjs/imageOverlay/utils/ImageOverlayController.js +1 -393
  8. package/lib/commonjs/imageOverlay/utils/componentMeasurement.js +1 -106
  9. package/lib/commonjs/imageOverlay/utils/devtoolsHook.js +1 -36
  10. package/lib/commonjs/imageOverlay/utils/fiberScanner.js +1 -102
  11. package/lib/commonjs/imageOverlay/utils/imageClipboard.js +1 -0
  12. package/lib/commonjs/imageOverlay/utils/imageClipboard.web.js +1 -0
  13. package/lib/commonjs/index.js +1 -59
  14. package/lib/commonjs/preset.js +1 -42
  15. package/lib/module/imageOverlay/components/ImageOverlayModal.js +1 -870
  16. package/lib/module/imageOverlay/components/ImageOverlayStandalone.js +1 -452
  17. package/lib/module/imageOverlay/components/OverlayControls.js +1 -249
  18. package/lib/module/imageOverlay/components/TargetList.js +1 -177
  19. package/lib/module/imageOverlay/types/index.js +1 -1
  20. package/lib/module/imageOverlay/utils/ImageOverlayController.js +1 -389
  21. package/lib/module/imageOverlay/utils/componentMeasurement.js +1 -102
  22. package/lib/module/imageOverlay/utils/devtoolsHook.js +1 -31
  23. package/lib/module/imageOverlay/utils/fiberScanner.js +1 -98
  24. package/lib/module/imageOverlay/utils/imageClipboard.js +1 -0
  25. package/lib/module/imageOverlay/utils/imageClipboard.web.js +1 -0
  26. package/lib/module/index.js +1 -35
  27. package/lib/module/preset.js +1 -38
  28. package/lib/typescript/imageOverlay/utils/imageClipboard.d.ts +3 -0
  29. package/lib/typescript/imageOverlay/utils/imageClipboard.web.d.ts +9 -0
  30. package/lib/web/index.mjs +4 -0
  31. package/package.json +32 -10
  32. package/lib/typescript/imageOverlay/components/ImageOverlayModal.d.ts.map +0 -1
  33. package/lib/typescript/imageOverlay/components/ImageOverlayStandalone.d.ts.map +0 -1
  34. package/lib/typescript/imageOverlay/components/OverlayControls.d.ts.map +0 -1
  35. package/lib/typescript/imageOverlay/components/TargetList.d.ts.map +0 -1
  36. package/lib/typescript/imageOverlay/types/index.d.ts.map +0 -1
  37. package/lib/typescript/imageOverlay/utils/ImageOverlayController.d.ts.map +0 -1
  38. package/lib/typescript/imageOverlay/utils/componentMeasurement.d.ts.map +0 -1
  39. package/lib/typescript/imageOverlay/utils/devtoolsHook.d.ts.map +0 -1
  40. package/lib/typescript/imageOverlay/utils/fiberScanner.d.ts.map +0 -1
  41. package/lib/typescript/index.d.ts.map +0 -1
  42. package/lib/typescript/preset.d.ts.map +0 -1
@@ -1,452 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Standalone overlay that renders:
5
- * - Component mode: highlight border + image overlay on a tagged component
6
- * - Free mode: draggable, resizable image anywhere on screen (aspect-ratio locked)
7
- *
8
- * Supports Normal, Difference, and Multiply blend modes.
9
- * Supports image inversion (flip X/Y) and position locking.
10
- * Auto-mounted by FloatingDevTools alongside other standalone overlays.
11
- */
12
-
13
- import React, { useState, useEffect, useRef, useMemo, useCallback } from "react";
14
- import { View, Text, Image as RNImage, StyleSheet, PanResponder, Dimensions } from "react-native";
15
- import { absoluteFill, monoFont } from "@buoy-gg/shared-ui";
16
- import { ImageOverlayController } from "../utils/ImageOverlayController";
17
-
18
- // ─── Overlay Image (handles flip transforms) ─────────────────────────────────
19
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
20
- function OverlayImage({
21
- uri,
22
- style,
23
- invertX,
24
- invertY
25
- }) {
26
- const transform = [];
27
- if (invertX) transform.push({
28
- scaleX: -1
29
- });
30
- if (invertY) transform.push({
31
- scaleY: -1
32
- });
33
- const flipStyle = transform.length > 0 ? {
34
- transform
35
- } : {};
36
- return /*#__PURE__*/_jsx(RNImage, {
37
- source: {
38
- uri
39
- },
40
- style: [style, flipStyle]
41
- // @ts-ignore
42
- ,
43
- pointerEvents: "none"
44
- });
45
- }
46
-
47
- // ─── Free Placement ───────────────────────────────────────────────────────────
48
-
49
- const FREE_MIN_SIZE = 30;
50
- function FreePlacement({
51
- imageUri,
52
- x,
53
- y,
54
- width,
55
- height,
56
- opacity,
57
- aspectRatio,
58
- invertX,
59
- invertY,
60
- locked
61
- }) {
62
- const [isInteracting, setIsInteracting] = useState(false);
63
- const startPosRef = useRef({
64
- x: 0,
65
- y: 0
66
- });
67
- const startDimsRef = useRef({
68
- x: 0,
69
- y: 0,
70
- width: 0,
71
- height: 0
72
- });
73
- const screen = Dimensions.get("window");
74
-
75
- // ── Drag ──
76
- const dragResponder = useMemo(() => PanResponder.create({
77
- onStartShouldSetPanResponder: () => !locked,
78
- onMoveShouldSetPanResponder: (_, g) => !locked && (Math.abs(g.dx) > 2 || Math.abs(g.dy) > 2),
79
- onPanResponderTerminationRequest: () => false,
80
- onPanResponderGrant: () => {
81
- const s = ImageOverlayController.getState();
82
- startPosRef.current = {
83
- x: s.freeX,
84
- y: s.freeY
85
- };
86
- setIsInteracting(true);
87
- },
88
- onPanResponderMove: (_, g) => {
89
- const s = ImageOverlayController.getState();
90
- const newX = Math.max(0, Math.min(startPosRef.current.x + g.dx, screen.width - s.freeWidth));
91
- const newY = Math.max(0, Math.min(startPosRef.current.y + g.dy, screen.height - s.freeHeight));
92
- ImageOverlayController.setFreePosition(newX, newY);
93
- },
94
- onPanResponderRelease: () => setIsInteracting(false),
95
- onPanResponderTerminate: () => setIsInteracting(false)
96
- }), [screen.width, screen.height, locked]);
97
-
98
- // ── Aspect-ratio-locked corner resize ──
99
- const createResizeHandler = useCallback(corner => PanResponder.create({
100
- onStartShouldSetPanResponder: () => !locked,
101
- onMoveShouldSetPanResponder: () => !locked,
102
- onPanResponderTerminationRequest: () => false,
103
- onPanResponderGrant: () => {
104
- const s = ImageOverlayController.getState();
105
- startDimsRef.current = {
106
- x: s.freeX,
107
- y: s.freeY,
108
- width: s.freeWidth,
109
- height: s.freeHeight
110
- };
111
- setIsInteracting(true);
112
- },
113
- onPanResponderMove: (_, g) => {
114
- const {
115
- dx,
116
- dy
117
- } = g;
118
- if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5) return;
119
- const start = startDimsRef.current;
120
- const ratio = aspectRatio > 0 ? aspectRatio : start.width / start.height;
121
- const absDx = Math.abs(dx);
122
- const absDy = Math.abs(dy);
123
- const useDx = absDx >= absDy;
124
- let newWidth;
125
- let newHeight;
126
- let newX = start.x;
127
- let newY = start.y;
128
- switch (corner) {
129
- case "bottomRight":
130
- {
131
- newWidth = useDx ? start.width + dx : (start.height + dy) * ratio;
132
- newWidth = Math.max(FREE_MIN_SIZE, Math.min(newWidth, screen.width - start.x));
133
- newHeight = newWidth / ratio;
134
- break;
135
- }
136
- case "bottomLeft":
137
- {
138
- newWidth = useDx ? start.width - dx : (start.height + dy) * ratio;
139
- newWidth = Math.max(FREE_MIN_SIZE, newWidth);
140
- newHeight = newWidth / ratio;
141
- newX = start.x + start.width - newWidth;
142
- newX = Math.max(0, newX);
143
- newWidth = Math.min(newWidth, start.x + start.width);
144
- newHeight = newWidth / ratio;
145
- break;
146
- }
147
- case "topRight":
148
- {
149
- newWidth = useDx ? start.width + dx : (start.height - dy) * ratio;
150
- newWidth = Math.max(FREE_MIN_SIZE, Math.min(newWidth, screen.width - start.x));
151
- newHeight = newWidth / ratio;
152
- newY = start.y + start.height - newHeight;
153
- newY = Math.max(0, newY);
154
- newHeight = Math.min(newHeight, start.y + start.height);
155
- newWidth = newHeight * ratio;
156
- break;
157
- }
158
- case "topLeft":
159
- {
160
- newWidth = useDx ? start.width - dx : (start.height - dy) * ratio;
161
- newWidth = Math.max(FREE_MIN_SIZE, newWidth);
162
- newHeight = newWidth / ratio;
163
- newX = start.x + start.width - newWidth;
164
- newY = start.y + start.height - newHeight;
165
- newX = Math.max(0, newX);
166
- newY = Math.max(0, newY);
167
- newWidth = Math.min(newWidth, start.x + start.width);
168
- newHeight = newWidth / ratio;
169
- newY = start.y + start.height - newHeight;
170
- break;
171
- }
172
- }
173
- newWidth = Math.max(FREE_MIN_SIZE, Math.round(newWidth));
174
- newHeight = Math.max(FREE_MIN_SIZE, Math.round(newHeight));
175
- ImageOverlayController.setFreeDimensions(newWidth, newHeight, Math.round(newX), Math.round(newY));
176
- },
177
- onPanResponderRelease: () => setIsInteracting(false),
178
- onPanResponderTerminate: () => setIsInteracting(false)
179
- }), [screen.width, screen.height, aspectRatio, locked]);
180
- const resizeHandlers = useMemo(() => ({
181
- topLeft: createResizeHandler("topLeft"),
182
- topRight: createResizeHandler("topRight"),
183
- bottomLeft: createResizeHandler("bottomLeft"),
184
- bottomRight: createResizeHandler("bottomRight")
185
- }), [createResizeHandler]);
186
- const imageStyle = {
187
- ...absoluteFill,
188
- opacity
189
- };
190
- return /*#__PURE__*/_jsxs(View, {
191
- style: {
192
- position: "absolute",
193
- left: x,
194
- top: y,
195
- width,
196
- height
197
- },
198
- children: [/*#__PURE__*/_jsx(View, {
199
- style: StyleSheet.absoluteFill,
200
- ...(locked ? {} : dragResponder.panHandlers),
201
- children: /*#__PURE__*/_jsx(OverlayImage, {
202
- uri: imageUri,
203
- style: imageStyle,
204
- invertX: invertX,
205
- invertY: invertY
206
- })
207
- }), /*#__PURE__*/_jsx(View, {
208
- pointerEvents: "none",
209
- style: [styles.freeBorder, isInteracting && styles.freeBorderActive, locked && styles.freeBorderLocked]
210
- }), !locked && /*#__PURE__*/_jsxs(_Fragment, {
211
- children: [/*#__PURE__*/_jsx(View, {
212
- ...resizeHandlers.topLeft.panHandlers,
213
- style: [styles.cornerWrapper, {
214
- top: -20,
215
- left: -20
216
- }],
217
- hitSlop: {
218
- top: 10,
219
- left: 10,
220
- right: 10,
221
- bottom: 10
222
- },
223
- children: /*#__PURE__*/_jsx(View, {
224
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
225
- })
226
- }), /*#__PURE__*/_jsx(View, {
227
- ...resizeHandlers.topRight.panHandlers,
228
- style: [styles.cornerWrapper, {
229
- top: -20,
230
- right: -20
231
- }],
232
- hitSlop: {
233
- top: 10,
234
- left: 10,
235
- right: 10,
236
- bottom: 10
237
- },
238
- children: /*#__PURE__*/_jsx(View, {
239
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
240
- })
241
- }), /*#__PURE__*/_jsx(View, {
242
- ...resizeHandlers.bottomLeft.panHandlers,
243
- style: [styles.cornerWrapper, {
244
- bottom: -20,
245
- left: -20
246
- }],
247
- hitSlop: {
248
- top: 10,
249
- left: 10,
250
- right: 10,
251
- bottom: 10
252
- },
253
- children: /*#__PURE__*/_jsx(View, {
254
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
255
- })
256
- }), /*#__PURE__*/_jsx(View, {
257
- ...resizeHandlers.bottomRight.panHandlers,
258
- style: [styles.cornerWrapper, {
259
- bottom: -20,
260
- right: -20
261
- }],
262
- hitSlop: {
263
- top: 10,
264
- left: 10,
265
- right: 10,
266
- bottom: 10
267
- },
268
- children: /*#__PURE__*/_jsx(View, {
269
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
270
- })
271
- })]
272
- })]
273
- });
274
- }
275
-
276
- // ─── Main Standalone Overlay ──────────────────────────────────────────────────
277
-
278
- export function ImageOverlayStandalone() {
279
- const [state, setState] = useState(() => ImageOverlayController.getState());
280
- useEffect(() => {
281
- return ImageOverlayController.subscribe(setState);
282
- }, []);
283
- const {
284
- mode,
285
- enabled,
286
- imageUri,
287
- imageWidth,
288
- imageHeight,
289
- targetRect,
290
- targetLabel,
291
- showOutline,
292
- opacity,
293
- scale,
294
- offsetX,
295
- offsetY,
296
- invertX,
297
- invertY,
298
- locked,
299
- freeX,
300
- freeY,
301
- freeWidth,
302
- freeHeight
303
- } = state;
304
- const aspectRatio = imageWidth && imageHeight && imageHeight > 0 ? imageWidth / imageHeight : 0;
305
-
306
- // ─── Free Placement Mode ───
307
- if (mode === "free" && enabled && imageUri) {
308
- return /*#__PURE__*/_jsx(View, {
309
- style: styles.overlay,
310
- pointerEvents: "box-none",
311
- nativeID: "image-overlay-standalone",
312
- children: /*#__PURE__*/_jsx(FreePlacement, {
313
- imageUri: imageUri,
314
- x: freeX,
315
- y: freeY,
316
- width: freeWidth,
317
- height: freeHeight,
318
- opacity: opacity,
319
- aspectRatio: aspectRatio,
320
- invertX: invertX,
321
- invertY: invertY,
322
- locked: locked
323
- })
324
- });
325
- }
326
-
327
- // ─── Component Match Mode ───
328
- if (!targetRect) return null;
329
- const showImage = enabled && imageUri;
330
- return /*#__PURE__*/_jsxs(View, {
331
- style: styles.overlay,
332
- pointerEvents: "box-none",
333
- nativeID: "image-overlay-standalone",
334
- children: [showOutline && /*#__PURE__*/_jsxs(_Fragment, {
335
- children: [/*#__PURE__*/_jsx(View, {
336
- pointerEvents: "none",
337
- nativeID: "__image_overlay_highlight__",
338
- style: [styles.highlight, {
339
- left: targetRect.x - 3,
340
- top: targetRect.y - 3,
341
- width: targetRect.width + 6,
342
- height: targetRect.height + 6
343
- }]
344
- }), targetLabel && /*#__PURE__*/_jsx(View, {
345
- pointerEvents: "none",
346
- style: [styles.label, {
347
- left: targetRect.x,
348
- top: targetRect.y - 20
349
- }],
350
- children: /*#__PURE__*/_jsx(Text, {
351
- style: styles.labelText,
352
- children: targetLabel
353
- })
354
- })]
355
- }), showImage && (() => {
356
- const w = (imageWidth ?? targetRect.width) * scale;
357
- const h = (imageHeight ?? targetRect.height) * scale;
358
- const centerX = targetRect.x + targetRect.width / 2;
359
- const centerY = targetRect.y + targetRect.height / 2;
360
- const imgStyle = {
361
- position: "absolute",
362
- left: centerX - w / 2 + offsetX,
363
- top: centerY - h / 2 + offsetY,
364
- width: w,
365
- height: h,
366
- opacity
367
- };
368
- return /*#__PURE__*/_jsx(OverlayImage, {
369
- uri: imageUri,
370
- style: imgStyle,
371
- invertX: invertX,
372
- invertY: invertY
373
- });
374
- })()]
375
- });
376
- }
377
- const styles = StyleSheet.create({
378
- overlay: {
379
- position: "absolute",
380
- top: 0,
381
- left: 0,
382
- right: 0,
383
- bottom: 0,
384
- zIndex: 999999,
385
- elevation: 999999,
386
- borderWidth: 0
387
- },
388
- highlight: {
389
- position: "absolute",
390
- borderWidth: 2,
391
- borderStyle: "dashed",
392
- borderColor: "#20C997",
393
- backgroundColor: "transparent"
394
- },
395
- label: {
396
- position: "absolute",
397
- backgroundColor: "#20C997",
398
- paddingHorizontal: 6,
399
- paddingVertical: 2,
400
- borderRadius: 3
401
- },
402
- labelText: {
403
- color: "#fff",
404
- fontSize: 10,
405
- fontWeight: "700",
406
- fontFamily: monoFont
407
- },
408
- freeBorder: {
409
- position: "absolute",
410
- top: -6,
411
- left: -6,
412
- right: -6,
413
- bottom: -6,
414
- borderWidth: 1,
415
- borderColor: "transparent",
416
- borderRadius: 4
417
- },
418
- freeBorderActive: {
419
- borderColor: "#20C997",
420
- borderStyle: "dashed"
421
- },
422
- freeBorderLocked: {
423
- borderColor: "#f59e0b",
424
- borderStyle: "solid"
425
- },
426
- cornerWrapper: {
427
- position: "absolute",
428
- width: 24,
429
- height: 24,
430
- zIndex: 1000,
431
- alignItems: "center",
432
- justifyContent: "center"
433
- },
434
- cornerHandle: {
435
- width: 12,
436
- height: 12,
437
- borderRadius: 6,
438
- backgroundColor: "#20C997",
439
- borderWidth: 2,
440
- borderColor: "#fff"
441
- },
442
- cornerHandleActive: {
443
- backgroundColor: "#10b981",
444
- shadowColor: "#10b981",
445
- shadowOffset: {
446
- width: 0,
447
- height: 0
448
- },
449
- shadowOpacity: 0.8,
450
- shadowRadius: 6
451
- }
452
- });
1
+ "use strict";import te,{useState as z,useEffect as N,useRef as B,useMemo as O,useCallback as U}from"react";import{View as i,Text as V,Image as Z,StyleSheet as j,PanResponder as k,Dimensions as J}from"react-native";import{absoluteFill as K,monoFont as Q}from"@buoy-gg/shared-ui";import{ImageOverlayController as R}from"../utils/ImageOverlayController";import{jsx as r,Fragment as q,jsxs as D}from"react/jsx-runtime";function G({uri:P,style:C,invertX:W,invertY:M}){const d=[];if(W)d.push({scaleX:-1});if(M)d.push({scaleY:-1});const x=d.length>0?{transform:d}:{};return r(Z,{testID:"buoy-internal-image-overlay",source:{uri:P},style:[C,x],pointerEvents:"none"})}const I=30;function $({imageUri:P,x:C,y:W,width:M,height:d,opacity:x,aspectRatio:m,invertX:n,invertY:X,locked:l}){const[b,f]=z(false);const _=B({x:0,y:0});const Y=B({x:0,y:0,width:0,height:0});const c=J.get("window");const E=O(()=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:(u,s)=>!l&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const u=R.getState();_.current={x:u.freeX,y:u.freeY};f(true)},onPanResponderMove:(u,s)=>{const H=R.getState();const p=Math.max(0,Math.min(_.current.x+s.dx,c.width-H.freeWidth));const g=Math.max(0,Math.min(_.current.y+s.dy,c.height-H.freeHeight));R.setFreePosition(p,g)},onPanResponderRelease:()=>f(false),onPanResponderTerminate:()=>f(false)}),[c.width,c.height,l]);const w=U(u=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:()=>!l,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=R.getState();Y.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};f(true)},onPanResponderMove:(s,H)=>{const{dx:p,dy:g}=H;if(Math.abs(p)<.5&&Math.abs(g)<.5)return;const e=Y.current;const h=m>0?m:e.width/e.height;const A=Math.abs(p);const T=Math.abs(g);const L=A>=T;let t;let a;let v=e.x;let y=e.y;switch(u){case"bottomRight":{t=L?e.width+p:(e.height+g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;break}case"bottomLeft":{t=L?e.width-p:(e.height+g)*h;t=Math.max(I,t);a=t/h;v=e.x+e.width-t;v=Math.max(0,v);t=Math.min(t,e.x+e.width);a=t/h;break}case"topRight":{t=L?e.width+p:(e.height-g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;y=e.y+e.height-a;y=Math.max(0,y);a=Math.min(a,e.y+e.height);t=a*h;break}case"topLeft":{t=L?e.width-p:(e.height-g)*h;t=Math.max(I,t);a=t/h;v=e.x+e.width-t;y=e.y+e.height-a;v=Math.max(0,v);y=Math.max(0,y);t=Math.min(t,e.x+e.width);a=t/h;y=e.y+e.height-a;break}}t=Math.max(I,Math.round(t));a=Math.max(I,Math.round(a));R.setFreeDimensions(t,a,Math.round(v),Math.round(y))},onPanResponderRelease:()=>f(false),onPanResponderTerminate:()=>f(false)}),[c.width,c.height,m,l]);const S=O(()=>({topLeft:w("topLeft"),topRight:w("topRight"),bottomLeft:w("bottomLeft"),bottomRight:w("bottomRight")}),[w]);const F={...K,opacity:x};return D(i,{style:{position:"absolute",left:C,top:W,width:M,height:d},pointerEvents:l?"none":"auto",children:[r(i,{style:j.absoluteFill,...l?{}:E.panHandlers,children:r(G,{uri:P,style:F,invertX:n,invertY:X})}),r(i,{pointerEvents:"none",style:[o.freeBorder,b&&o.freeBorderActive,l&&o.freeBorderLocked]}),!l&&D(q,{children:[r(i,{...S.topLeft.panHandlers,style:[o.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.topRight.panHandlers,style:[o.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomLeft.panHandlers,style:[o.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomRight.panHandlers,style:[o.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})})]})]})}export function ImageOverlayStandalone(){const[P,C]=z(()=>R.getState());N(()=>{return R.subscribe(C)},[]);const{mode:W,enabled:M,imageUri:d,imageWidth:x,imageHeight:m,targetRect:n,targetLabel:X,showOutline:l,opacity:b,scale:f,offsetX:_,offsetY:Y,invertX:c,invertY:E,locked:w,freeX:S,freeY:F,freeWidth:u,freeHeight:s}=P;const H=x&&m&&m>0?x/m:0;if(W==="free"&&M&&d){return r(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:r($,{imageUri:d,x:S,y:F,width:u,height:s,opacity:b,aspectRatio:H,invertX:c,invertY:E,locked:w})})}if(!n)return null;const p=M&&d;return D(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[l&&D(q,{children:[r(i,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",style:[o.highlight,{left:n.x-3,top:n.y-3,width:n.width+6,height:n.height+6}]}),X&&r(i,{pointerEvents:"none",style:[o.label,{left:n.x,top:n.y-20}],children:r(V,{style:o.labelText,children:X})})]}),p&&(()=>{const g=(x??n.width)*f;const e=(m??n.height)*f;const h=n.x+n.width/2;const A=n.y+n.height/2;const T={position:"absolute",left:h-g/2+_,top:A-e/2+Y,width:g,height:e,opacity:b};return r(G,{uri:d,style:T,invertX:c,invertY:E})})()]})}const o=j.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:Q},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});