@archireport/react-native-svg-draw 1.0.1 → 1.1.0

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 (53) hide show
  1. package/lib/commonjs/components/DrawCore/ColorSlider.js +8 -5
  2. package/lib/commonjs/components/DrawCore/ColorSlider.js.map +1 -1
  3. package/lib/commonjs/components/DrawCore/CurrentAnimatedItem.js +56 -6
  4. package/lib/commonjs/components/DrawCore/CurrentAnimatedItem.js.map +1 -1
  5. package/lib/commonjs/components/DrawCore/DrawPad.js +4 -4
  6. package/lib/commonjs/components/DrawCore/DrawPad.js.map +1 -1
  7. package/lib/commonjs/components/DrawCore/Item.js +3 -5
  8. package/lib/commonjs/components/DrawCore/Item.js.map +1 -1
  9. package/lib/commonjs/components/DrawCore/StrokeSlider.js +5 -2
  10. package/lib/commonjs/components/DrawCore/StrokeSlider.js.map +1 -1
  11. package/lib/commonjs/components/DrawCore/index.js +139 -52
  12. package/lib/commonjs/components/DrawCore/index.js.map +1 -1
  13. package/lib/commonjs/components/DrawWithOptions/CancelSvg.js +35 -0
  14. package/lib/commonjs/components/DrawWithOptions/CancelSvg.js.map +1 -0
  15. package/lib/commonjs/components/DrawWithOptions/PenSvg.js +27 -0
  16. package/lib/commonjs/components/DrawWithOptions/PenSvg.js.map +1 -0
  17. package/lib/commonjs/components/DrawWithOptions/index.js +30 -1
  18. package/lib/commonjs/components/DrawWithOptions/index.js.map +1 -1
  19. package/lib/module/components/DrawCore/ColorSlider.js +9 -6
  20. package/lib/module/components/DrawCore/ColorSlider.js.map +1 -1
  21. package/lib/module/components/DrawCore/CurrentAnimatedItem.js +53 -7
  22. package/lib/module/components/DrawCore/CurrentAnimatedItem.js.map +1 -1
  23. package/lib/module/components/DrawCore/DrawPad.js +4 -4
  24. package/lib/module/components/DrawCore/DrawPad.js.map +1 -1
  25. package/lib/module/components/DrawCore/Item.js +2 -6
  26. package/lib/module/components/DrawCore/Item.js.map +1 -1
  27. package/lib/module/components/DrawCore/StrokeSlider.js +5 -2
  28. package/lib/module/components/DrawCore/StrokeSlider.js.map +1 -1
  29. package/lib/module/components/DrawCore/index.js +140 -53
  30. package/lib/module/components/DrawCore/index.js.map +1 -1
  31. package/lib/module/components/DrawWithOptions/CancelSvg.js +22 -0
  32. package/lib/module/components/DrawWithOptions/CancelSvg.js.map +1 -0
  33. package/lib/module/components/DrawWithOptions/PenSvg.js +14 -0
  34. package/lib/module/components/DrawWithOptions/PenSvg.js.map +1 -0
  35. package/lib/module/components/DrawWithOptions/index.js +28 -1
  36. package/lib/module/components/DrawWithOptions/index.js.map +1 -1
  37. package/lib/typescript/components/DrawCore/ColorSlider.d.ts +2 -1
  38. package/lib/typescript/components/DrawCore/CurrentAnimatedItem.d.ts +2 -1
  39. package/lib/typescript/components/DrawCore/StrokeSlider.d.ts +2 -1
  40. package/lib/typescript/components/DrawCore/index.d.ts +1 -0
  41. package/lib/typescript/components/DrawWithOptions/CancelSvg.d.ts +2 -0
  42. package/lib/typescript/components/DrawWithOptions/PenSvg.d.ts +2 -0
  43. package/package.json +5 -5
  44. package/src/components/DrawCore/ColorSlider.tsx +11 -6
  45. package/src/components/DrawCore/CurrentAnimatedItem.tsx +59 -8
  46. package/src/components/DrawCore/DrawPad.tsx +2 -2
  47. package/src/components/DrawCore/Item.tsx +3 -11
  48. package/src/components/DrawCore/StrokeSlider.tsx +5 -1
  49. package/src/components/DrawCore/index.tsx +1105 -971
  50. package/src/components/DrawWithOptions/CancelSvg.tsx +23 -0
  51. package/src/components/DrawWithOptions/PenSvg.tsx +14 -0
  52. package/src/components/DrawWithOptions/index.tsx +34 -0
  53. package/src/types.d.ts +4 -1
@@ -2,6 +2,7 @@ import React, {
2
2
  useCallback,
3
3
  useEffect,
4
4
  useImperativeHandle,
5
+ useReducer,
5
6
  useRef,
6
7
  useState,
7
8
  } from 'react';
@@ -85,10 +86,10 @@ const styles = StyleSheet.create({
85
86
  },
86
87
  });
87
88
 
88
- function pDistance(
89
+ const pDistance = (
89
90
  point: { x: number; y: number },
90
91
  line: { x1: number; x2: number; y1: number; y2: number }
91
- ) {
92
+ ) => {
92
93
  'worklet';
93
94
  const { x1, x2, y1, y2 } = line;
94
95
  const { x, y } = point;
@@ -122,7 +123,7 @@ function pDistance(
122
123
  var dx = x - xx;
123
124
  var dy = y - yy;
124
125
  return Math.sqrt(dx * dx + dy * dy);
125
- }
126
+ };
126
127
 
127
128
  const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
128
129
 
@@ -150,7 +151,7 @@ type Context = {
150
151
  const drawNewItem = (
151
152
  mode: Animated.SharedValue<DrawItemType>,
152
153
  currentItem: Animated.SharedValue<DrawItem | null>,
153
- updateDoneItems: (item: DrawItem) => void,
154
+ addDoneItem: (item: DrawItem) => void,
154
155
  position: { x: number; y: number },
155
156
  style: {
156
157
  textBaseHeight: Animated.SharedValue<number | null>;
@@ -161,7 +162,7 @@ const drawNewItem = (
161
162
  'worklet';
162
163
 
163
164
  if (currentItem.value) {
164
- runOnJS(updateDoneItems)(currentItem.value);
165
+ runOnJS(addDoneItem)(currentItem.value);
165
166
  }
166
167
 
167
168
  switch (mode.value) {
@@ -247,6 +248,71 @@ const onTextHeightUpdate = (
247
248
  }
248
249
  };
249
250
 
251
+ type Action =
252
+ | { type: 'ADD_DONE_ITEM'; item: DrawItem }
253
+ | { type: 'DELETE_DONE_ITEM'; indice: number }
254
+ | {
255
+ type: 'ADD_SCREEN_STATE';
256
+ currentItem: DrawItem | null;
257
+ }
258
+ | {
259
+ type: 'CANCEL';
260
+ onCancelChange?: (cancel: boolean) => void;
261
+ };
262
+
263
+ const reducerDrawStates = (
264
+ drawStates: { doneItems: DrawItem[]; screenStates: DrawItem[][] },
265
+ action: Action
266
+ ) => {
267
+ 'worklet';
268
+ switch (action.type) {
269
+ case 'ADD_DONE_ITEM':
270
+ return {
271
+ ...drawStates,
272
+ doneItems: drawStates.doneItems.concat(action.item),
273
+ };
274
+ case 'DELETE_DONE_ITEM':
275
+ const newDoneItems = drawStates.doneItems;
276
+ newDoneItems.splice(action.indice, 1);
277
+ return {
278
+ ...drawStates,
279
+ doneItems: newDoneItems,
280
+ };
281
+ case 'ADD_SCREEN_STATE':
282
+ if (action.currentItem) {
283
+ return {
284
+ ...drawStates,
285
+ screenStates: drawStates.screenStates.concat([
286
+ [...drawStates.doneItems, action.currentItem],
287
+ ]),
288
+ };
289
+ } else {
290
+ return {
291
+ ...drawStates,
292
+ screenStates: drawStates.screenStates.concat([
293
+ [...drawStates.doneItems],
294
+ ]),
295
+ };
296
+ }
297
+
298
+ case 'CANCEL':
299
+ const len = drawStates.screenStates.length;
300
+ if (len > 1) {
301
+ const newScreenStates = drawStates.screenStates;
302
+ newScreenStates.pop();
303
+ if (newScreenStates.length === 1) {
304
+ action.onCancelChange?.(false);
305
+ }
306
+ return {
307
+ doneItems: drawStates.screenStates[len - 2],
308
+ screenStates: newScreenStates,
309
+ };
310
+ } else {
311
+ return drawStates;
312
+ }
313
+ }
314
+ };
315
+
250
316
  const DrawCore = React.forwardRef<
251
317
  DrawCoreProps,
252
318
  {
@@ -254,1046 +320,1114 @@ const DrawCore = React.forwardRef<
254
320
  image?: ImageRequireSource | ImageURISource;
255
321
  linearGradient: React.ComponentType<{ colors: any[] } & ViewProps>;
256
322
  onSelectionChange?: (selected: boolean) => void;
323
+ onCancelChange?: (cancel: boolean) => void;
257
324
  }
258
- >(({ drawingMode, image, linearGradient, onSelectionChange }, ref) => {
259
- const mode = useSharedValue<DrawItemType>('pen');
325
+ >(
326
+ (
327
+ { drawingMode, image, linearGradient, onSelectionChange, onCancelChange },
328
+ ref
329
+ ) => {
330
+ const mode = useSharedValue<DrawItemType>('pen');
260
331
 
261
- const [drawRegion, setDrawRegion] = useState<Size | null>(null);
332
+ const [drawRegion, setDrawRegion] = useState<Size | null>(null);
262
333
 
263
- const [originalImageSize, setOriginalImageSize] = useState<Size | null>(null);
334
+ const [originalImageSize, setOriginalImageSize] =
335
+ useState<Size | null>(null);
264
336
 
265
- const [imageSize, setImageSize] = useState<Size | null>(null);
337
+ const [imageSize, setImageSize] = useState<Size | null>(null);
266
338
 
267
- const drawContainer = useRef<View>(null);
339
+ const drawContainer = useRef<View>(null);
268
340
 
269
- const viewShot = useRef<ViewShot>(null);
341
+ const viewShot = useRef<ViewShot>(null);
270
342
 
271
- const [textVal, setTextVal] = useState<string>('');
343
+ const [textVal, setTextVal] = useState<string>('');
272
344
 
273
- const currentItem = useSharedValue<DrawItem | null>(null);
345
+ const currentItem = useSharedValue<DrawItem | null>(null);
274
346
 
275
- const initialItem = useSharedValue<DrawItem | null>(null);
347
+ const initialItem = useSharedValue<DrawItem | null>(null);
276
348
 
277
- const [doneItems, setDoneItems] = useState<DrawItem[]>([]);
349
+ const [drawStates, dispatchDrawStates] = useReducer(reducerDrawStates, {
350
+ doneItems: [],
351
+ screenStates: [[]],
352
+ });
278
353
 
279
- const textBaseHeight = useSharedValue<number | null>(null);
354
+ const textBaseHeight = useSharedValue<number | null>(null);
280
355
 
281
- const updateDoneItems = useCallback((done: DrawItem) => {
282
- setDoneItems((previous) => previous.concat(done));
283
- }, []);
356
+ const addDoneItem = useCallback((item: DrawItem) => {
357
+ dispatchDrawStates({ type: 'ADD_DONE_ITEM', item: item });
358
+ }, []);
284
359
 
285
- useImperativeHandle(
286
- ref,
287
- () => ({
288
- drawingContainer: drawContainer,
289
- deleteSelectedItem: () => {
290
- if (currentItem.value) {
291
- currentItem.value = null;
292
- }
293
- onSelectionChange?.(false);
294
- },
295
- takeSnapshot: async (): Promise<string | undefined> => {
296
- if (currentItem.value) {
297
- updateDoneItems(currentItem.value);
298
- currentItem.value = null;
299
- }
300
- return viewShot.current?.capture?.();
301
- },
302
- }),
303
- [currentItem, onSelectionChange, updateDoneItems]
304
- );
305
-
306
- useEffect(() => {
307
- mode.value = drawingMode;
308
- if (currentItem.value) {
309
- updateDoneItems(currentItem.value);
310
- }
311
- currentItem.value = null;
312
- onSelectionChange?.(false);
313
- }, [drawingMode, mode, currentItem, updateDoneItems, onSelectionChange]);
360
+ const deleteDoneItem = useCallback((indice: number) => {
361
+ dispatchDrawStates({ type: 'DELETE_DONE_ITEM', indice: indice });
362
+ }, []);
314
363
 
315
- const addNewItem = runOnJS(updateDoneItems);
364
+ const addScreenStates = useCallback((item: DrawItem | null) => {
365
+ dispatchDrawStates({
366
+ type: 'ADD_SCREEN_STATE',
367
+ currentItem: item,
368
+ });
369
+ }, []);
316
370
 
317
- const strokeWidth = useSharedValue<number>(2);
371
+ const cancelAction = useCallback(() => {
372
+ dispatchDrawStates({
373
+ type: 'CANCEL',
374
+ onCancelChange: onCancelChange,
375
+ });
376
+ }, [onCancelChange]);
377
+
378
+ useImperativeHandle(
379
+ ref,
380
+ () => ({
381
+ drawingContainer: drawContainer,
382
+ deleteSelectedItem: () => {
383
+ if (currentItem.value) {
384
+ currentItem.value = null;
385
+ addScreenStates(null);
386
+ }
387
+ onSelectionChange?.(false);
388
+ onCancelChange?.(true);
389
+ },
390
+ cancelLastAction: () => {
391
+ onSelectionChange?.(false);
392
+ if (currentItem.value) {
393
+ currentItem.value = null;
394
+ }
395
+ cancelAction();
396
+ },
397
+ takeSnapshot: async (): Promise<string | undefined> => {
398
+ if (currentItem.value) {
399
+ addDoneItem(currentItem.value);
400
+ currentItem.value = null;
401
+ }
402
+ return viewShot.current?.capture?.();
403
+ },
404
+ }),
405
+ [
406
+ currentItem,
407
+ onSelectionChange,
408
+ onCancelChange,
409
+ addScreenStates,
410
+ cancelAction,
411
+ addDoneItem,
412
+ ]
413
+ );
414
+
415
+ useEffect(() => {
416
+ mode.value = drawingMode;
417
+ if (currentItem.value) {
418
+ addDoneItem(currentItem.value);
419
+ }
420
+ currentItem.value = null;
421
+ onSelectionChange?.(false);
422
+ }, [drawingMode, mode, currentItem, onSelectionChange, addDoneItem]);
318
423
 
319
- const color = useSharedValue<hslColor>('hsl(0, 100%, 0%)');
424
+ const strokeWidth = useSharedValue<number>(2);
320
425
 
321
- const panPosition = useSharedValue(0);
426
+ const color = useSharedValue<hslColor>('hsl(0, 100%, 0%)');
322
427
 
323
- const showTextInput = useSharedValue(false);
428
+ const panPosition = useSharedValue(0);
324
429
 
325
- const textFocus = useCallback(() => {
326
- textInputRef.current?.focus();
327
- }, []);
430
+ const showTextInput = useSharedValue(false);
328
431
 
329
- useEffect(() => {
330
- if (currentItem.value?.type === 'text') {
331
- currentItem.value = {
332
- data: currentItem.value.data,
333
- type: currentItem.value.type,
334
- strokeWidth: currentItem.value.strokeWidth,
335
- color: currentItem.value.color,
336
- text: textVal,
337
- };
338
- }
339
- }, [currentItem, textVal]);
432
+ const textFocus = useCallback(() => {
433
+ textInputRef.current?.focus();
434
+ }, []);
340
435
 
341
- const onGestureEvent = useAnimatedGestureHandler<
342
- PanGestureHandlerGestureEvent,
343
- Context
344
- >(
345
- {
346
- onStart: ({ x, y }, ctx) => {
347
- const startX = x;
348
- const startY = y;
349
- ctx.startX = startX;
350
- ctx.startY = startY;
351
- ctx.newlyCreated = false;
436
+ const onColorStrokeChange = useCallback(() => {
437
+ if (currentItem.value) {
438
+ addScreenStates(currentItem.value);
439
+ }
440
+ }, [addScreenStates, currentItem.value]);
441
+
442
+ useEffect(() => {
443
+ if (currentItem.value?.type === 'text') {
444
+ currentItem.value = {
445
+ data: currentItem.value.data,
446
+ type: currentItem.value.type,
447
+ strokeWidth: currentItem.value.strokeWidth,
448
+ color: currentItem.value.color,
449
+ text: textVal,
450
+ };
451
+ }
452
+ }, [currentItem, textVal]);
352
453
 
353
- panPosition.value = withTiming(RIGHT_PANE_WIDTH);
454
+ const onGestureEvent = useAnimatedGestureHandler<
455
+ PanGestureHandlerGestureEvent,
456
+ Context
457
+ >(
458
+ {
459
+ onStart: ({ x: startX, y: startY }, ctx) => {
460
+ ctx.startX = startX;
461
+ ctx.startY = startY;
462
+ ctx.newlyCreated = false;
354
463
 
355
- initialItem.value = currentItem.value;
464
+ panPosition.value = withTiming(RIGHT_PANE_WIDTH);
356
465
 
357
- switch (currentItem.value?.type) {
358
- case 'ellipse':
359
- const cx =
360
- typeof currentItem.value.data.cx === 'string'
361
- ? parseFloat(currentItem.value.data.cx)
362
- : currentItem.value.data.cx || 0;
363
- const cy =
364
- typeof currentItem.value.data.cy === 'string'
365
- ? parseFloat(currentItem.value.data.cy)
366
- : currentItem.value.data.cy || 0;
367
- const rx =
368
- typeof currentItem.value.data.rx === 'string'
369
- ? parseFloat(currentItem.value.data.rx)
370
- : currentItem.value.data.rx || 0;
371
- const ry =
372
- typeof currentItem.value.data.ry === 'string'
373
- ? parseFloat(currentItem.value.data.ry)
374
- : currentItem.value.data.ry || 0;
375
-
376
- if (
377
- startX <= cx + THRESHOLD &&
378
- startX >= cx - THRESHOLD &&
379
- startY <= cy - ry + THRESHOLD &&
380
- startY >= cy - ry - THRESHOLD
381
- ) {
382
- ctx.zone = 'TOP';
383
- } else if (
384
- startX <= cx + THRESHOLD &&
385
- startX >= cx - THRESHOLD &&
386
- startY <= cy + ry + THRESHOLD &&
387
- startY >= cy + ry - THRESHOLD
388
- ) {
389
- ctx.zone = 'BOTTOM';
390
- } else if (
391
- startY <= cy + THRESHOLD &&
392
- startY >= cy - THRESHOLD &&
393
- startX <= cx - rx + THRESHOLD &&
394
- startX >= cx - rx - THRESHOLD
395
- ) {
396
- ctx.zone = 'LEFT';
397
- } else if (
398
- startY <= cy + THRESHOLD &&
399
- startY >= cy - THRESHOLD &&
400
- startX <= cx + rx + THRESHOLD &&
401
- startX >= cx + rx - THRESHOLD
402
- ) {
403
- ctx.zone = 'RIGHT';
404
- } else if (
405
- ((rx > 0 && startX > cx - rx && startX < cx + rx) ||
406
- (rx < 0 && startX < cx - rx && startX > cx + rx)) &&
407
- ((ry > 0 && startY > cy - ry && startY < cy + ry) ||
408
- (ry < 0 && startY < cy - ry && startY > cy + ry))
409
- ) {
410
- ctx.zone = 'CENTER';
411
- } else {
412
- ctx.zone = 'OUT';
413
- initialItem.value = null;
414
- }
466
+ initialItem.value = currentItem.value;
415
467
 
416
- break;
417
- case 'rectangle':
418
- const x =
419
- typeof currentItem.value.data.x === 'string'
420
- ? parseFloat(currentItem.value.data.x)
421
- : currentItem.value.data.x || 0;
422
- const y =
423
- typeof currentItem.value.data.y === 'string'
424
- ? parseFloat(currentItem.value.data.y)
425
- : currentItem.value.data.y || 0;
426
- const height =
427
- typeof currentItem.value.data.height === 'string'
428
- ? parseFloat(currentItem.value.data.height)
429
- : currentItem.value.data.height || 0;
430
- const width =
431
- typeof currentItem.value.data.width === 'string'
432
- ? parseFloat(currentItem.value.data.width)
433
- : currentItem.value.data.width || 0;
434
-
435
- if (startX <= x + THRESHOLD && startX >= x - THRESHOLD) {
436
- if (startY <= y + THRESHOLD && startY >= y - THRESHOLD) {
437
- ctx.zone = 'TOP_LEFT';
468
+ switch (currentItem.value?.type) {
469
+ case 'ellipse':
470
+ const cx =
471
+ typeof currentItem.value.data.cx === 'string'
472
+ ? parseFloat(currentItem.value.data.cx)
473
+ : currentItem.value.data.cx || 0;
474
+ const cy =
475
+ typeof currentItem.value.data.cy === 'string'
476
+ ? parseFloat(currentItem.value.data.cy)
477
+ : currentItem.value.data.cy || 0;
478
+ const rx =
479
+ typeof currentItem.value.data.rx === 'string'
480
+ ? parseFloat(currentItem.value.data.rx)
481
+ : currentItem.value.data.rx || 0;
482
+ const ry =
483
+ typeof currentItem.value.data.ry === 'string'
484
+ ? parseFloat(currentItem.value.data.ry)
485
+ : currentItem.value.data.ry || 0;
486
+
487
+ if (
488
+ startX <= cx + THRESHOLD &&
489
+ startX >= cx - THRESHOLD &&
490
+ startY <= cy - ry + THRESHOLD &&
491
+ startY >= cy - ry - THRESHOLD
492
+ ) {
493
+ ctx.zone = 'TOP';
438
494
  } else if (
439
- startY <= y + height + THRESHOLD &&
440
- startY >= y + height - THRESHOLD
495
+ startX <= cx + THRESHOLD &&
496
+ startX >= cx - THRESHOLD &&
497
+ startY <= cy + ry + THRESHOLD &&
498
+ startY >= cy + ry - THRESHOLD
441
499
  ) {
442
- ctx.zone = 'BOTTOM_LEFT';
443
- }
444
- } else if (
445
- startX <= x + width + THRESHOLD &&
446
- startX >= x + width - THRESHOLD
447
- ) {
448
- if (startY <= y + THRESHOLD && startY >= y - THRESHOLD) {
449
- ctx.zone = 'TOP_RIGHT';
500
+ ctx.zone = 'BOTTOM';
450
501
  } else if (
451
- startY <= y + height + THRESHOLD &&
452
- startY >= y + height - THRESHOLD
502
+ startY <= cy + THRESHOLD &&
503
+ startY >= cy - THRESHOLD &&
504
+ startX <= cx - rx + THRESHOLD &&
505
+ startX >= cx - rx - THRESHOLD
453
506
  ) {
454
- ctx.zone = 'BOTTOM_RIGHT';
455
- }
456
- } else if (
457
- ((width > 0 && startX > x && startX < x + width) ||
458
- (width < 0 && startX < x && startX > x + width)) &&
459
- ((height > 0 && startY > y && startY < y + height) ||
460
- (height < 0 && startY < y && startY > y + height))
461
- ) {
462
- ctx.zone = 'CENTER';
463
- } else {
464
- ctx.zone = 'OUT';
465
- initialItem.value = null;
466
- }
467
-
468
- break;
469
- case 'doubleHead':
470
- case 'singleHead':
471
- const x1 =
472
- typeof currentItem.value.data.x1 === 'string'
473
- ? parseFloat(currentItem.value.data.x1)
474
- : currentItem.value.data.x1 || 0;
475
- const y1 =
476
- typeof currentItem.value.data.y1 === 'string'
477
- ? parseFloat(currentItem.value.data.y1)
478
- : currentItem.value.data.y1 || 0;
479
- const x2 =
480
- typeof currentItem.value.data.x2 === 'string'
481
- ? parseFloat(currentItem.value.data.x2)
482
- : currentItem.value.data.x2 || 0;
483
- const y2 =
484
- typeof currentItem.value.data.y2 === 'string'
485
- ? parseFloat(currentItem.value.data.y2)
486
- : currentItem.value.data.y2 || 0;
487
-
488
- if (
489
- startX <= x1 + THRESHOLD &&
490
- startX >= x1 - THRESHOLD &&
491
- startY <= y1 + THRESHOLD &&
492
- startY >= y1 - THRESHOLD
493
- ) {
494
- ctx.zone = 'TOP';
495
- } else if (
496
- startX <= x2 + THRESHOLD &&
497
- startX >= x2 - THRESHOLD &&
498
- startY - THRESHOLD <= y2 + THRESHOLD &&
499
- startY + THRESHOLD >= y2 - THRESHOLD
500
- ) {
501
- ctx.zone = 'BOTTOM';
502
- } else if (
503
- pDistance({ x: startX, y: startY }, { x1, x2, y1, y2 }) <=
504
- THRESHOLD &&
505
- ((startX > x1 && startX < x2) || (startX < x1 && startX > x2)) &&
506
- ((startY > y1 && startY < y2) || (startY < y1 && startY > y2))
507
- ) {
508
- ctx.zone = 'CENTER';
509
- } else {
510
- ctx.zone = 'OUT';
511
- initialItem.value = null;
512
- }
513
-
514
- break;
515
- case 'text':
516
- const xText =
517
- typeof currentItem.value.data.x === 'string'
518
- ? parseFloat(currentItem.value.data.x)
519
- : currentItem.value.data.x || 0;
520
- const yText =
521
- typeof currentItem.value.data.y === 'string'
522
- ? parseFloat(currentItem.value.data.y)
523
- : currentItem.value.data.y || 0;
524
- const widthText =
525
- typeof currentItem.value.data.width === 'string'
526
- ? parseFloat(currentItem.value.data.width)
527
- : currentItem.value.data.width || 0;
528
- const heightText =
529
- typeof currentItem.value.data.height === 'string'
530
- ? parseFloat(currentItem.value.data.height)
531
- : currentItem.value.data.height || 0;
532
-
533
- if (
534
- startX <= xText + THRESHOLD &&
535
- startX >= xText - THRESHOLD &&
536
- startY <= yText + heightText / 2 + THRESHOLD &&
537
- startY >= yText + heightText / 2 - THRESHOLD
538
- ) {
539
- ctx.zone = 'LEFT';
540
- } else if (
541
- startX <= xText + widthText + THRESHOLD &&
542
- startX >= xText + widthText - THRESHOLD &&
543
- startY <= yText + heightText / 2 + THRESHOLD &&
544
- startY >= yText + heightText / 2 - THRESHOLD
545
- ) {
546
- ctx.zone = 'RIGHT';
547
- } else if (
548
- ((widthText > 0 &&
549
- startX > xText &&
550
- startX < xText + widthText) ||
551
- (widthText < 0 &&
552
- startX < xText &&
553
- startX > xText + widthText)) &&
554
- ((heightText > 0 &&
555
- startY > yText &&
556
- startY < yText + heightText) ||
557
- (heightText < 0 &&
558
- startY < yText &&
559
- startY > yText + heightText))
560
- ) {
561
- ctx.zone = 'CENTER';
562
- } else {
563
- ctx.zone = 'OUT';
564
- initialItem.value = null;
565
- }
566
-
567
- break;
568
- case 'pen':
569
- if (
570
- currentItem.value.data.some(
571
- (p) =>
572
- startX <= p.x + THRESHOLD &&
573
- startX >= p.x - THRESHOLD &&
574
- startY <= p.y + THRESHOLD &&
575
- startY >= p.y - THRESHOLD
576
- )
577
- ) {
578
- ctx.zone = 'CENTER';
579
- } else {
580
- ctx.zone = 'OUT';
581
- initialItem.value = null;
582
- }
583
- break;
584
- default:
585
- ctx.zone = 'OUT';
586
- initialItem.value = null;
587
- break;
588
- }
589
- },
590
- onActive: ({ x, y, translationX, translationY }, ctx) => {
591
- const { startX, startY, zone, newlyCreated } = ctx;
592
- if (zone === 'OUT' && newlyCreated === false) {
593
- ctx.newlyCreated = true;
594
- if (mode.value === 'text') {
595
- runOnJS(setTextVal)('');
596
- }
597
-
598
- drawNewItem(
599
- mode,
600
- currentItem,
601
- addNewItem,
602
- { x: startX, y: startY },
603
- { textBaseHeight, strokeWidth, color }
604
- );
605
- onSelectionChange && runOnJS(onSelectionChange)(true);
606
- }
607
- switch (currentItem.value?.type) {
608
- case 'pen':
609
- if (
610
- initialItem.value?.type === currentItem.value.type &&
611
- zone === 'CENTER'
612
- ) {
613
- currentItem.value = {
614
- type: 'pen',
615
- strokeWidth: currentItem.value.strokeWidth,
616
- color: currentItem.value.color,
617
- data: initialItem.value.data.map((p) => ({
618
- x: p.x + translationX,
619
- y: p.y + translationY,
620
- })),
621
- };
622
- } else {
623
- currentItem.value = {
624
- type: 'pen',
625
- strokeWidth: currentItem.value.strokeWidth,
626
- color: currentItem.value.color,
627
- data: currentItem.value.data.concat({
628
- x: x,
629
- y: y,
630
- }),
631
- };
632
- }
633
- break;
634
- case 'ellipse':
635
- if (initialItem.value?.type === currentItem.value.type) {
636
- const rx =
637
- typeof initialItem.value.data.rx === 'string'
638
- ? parseFloat(initialItem.value?.data.rx)
639
- : initialItem.value.data.rx || 0;
640
-
641
- const ry =
642
- typeof initialItem.value.data.ry === 'string'
643
- ? parseFloat(initialItem.value.data.ry)
644
- : initialItem.value.data.ry || 0;
645
-
646
- const cx =
647
- typeof initialItem.value.data.cx === 'string'
648
- ? parseFloat(initialItem.value.data.cx)
649
- : initialItem.value.data.cx || 0;
650
-
651
- const cy =
652
- typeof initialItem.value.data.cy === 'string'
653
- ? parseFloat(initialItem.value.data.cy)
654
- : initialItem.value.data.cy || 0;
655
-
656
- switch (zone) {
657
- case 'TOP':
658
- currentItem.value = {
659
- type: currentItem.value.type,
660
- strokeWidth: currentItem.value.strokeWidth,
661
- color: currentItem.value.color,
662
- data: {
663
- cx: cx,
664
- cy: cy + translationY,
665
- rx: rx,
666
- ry: ry - translationY,
667
- },
668
- };
669
- break;
670
- case 'BOTTOM':
671
- currentItem.value = {
672
- type: currentItem.value.type,
673
- strokeWidth: currentItem.value.strokeWidth,
674
- color: currentItem.value.color,
675
- data: {
676
- cx: cx,
677
- cy: cy + translationY,
678
- rx: rx,
679
- ry: ry + translationY,
680
- },
681
- };
682
- break;
683
- case 'LEFT':
684
- currentItem.value = {
685
- type: currentItem.value.type,
686
- strokeWidth: currentItem.value.strokeWidth,
687
- color: currentItem.value.color,
688
- data: {
689
- cx: cx + translationX,
690
- cy: cy,
691
- rx: rx - translationX,
692
- ry: ry,
693
- },
694
- };
695
- break;
696
- case 'RIGHT':
697
- currentItem.value = {
698
- type: currentItem.value.type,
699
- strokeWidth: currentItem.value.strokeWidth,
700
- color: currentItem.value.color,
701
- data: {
702
- cx: cx + translationX,
703
- cy: cy,
704
- rx: rx + translationX,
705
- ry: ry,
706
- },
707
- };
708
- break;
709
- case 'CENTER':
710
- currentItem.value = {
711
- type: currentItem.value.type,
712
- strokeWidth: currentItem.value.strokeWidth,
713
- color: currentItem.value.color,
714
- data: {
715
- cx: cx + translationX,
716
- cy: cy + translationY,
717
- rx: rx,
718
- ry: ry,
719
- },
720
- };
721
- break;
507
+ ctx.zone = 'LEFT';
508
+ } else if (
509
+ startY <= cy + THRESHOLD &&
510
+ startY >= cy - THRESHOLD &&
511
+ startX <= cx + rx + THRESHOLD &&
512
+ startX >= cx + rx - THRESHOLD
513
+ ) {
514
+ ctx.zone = 'RIGHT';
515
+ } else if (
516
+ ((rx > 0 && startX > cx - rx && startX < cx + rx) ||
517
+ (rx < 0 && startX < cx - rx && startX > cx + rx)) &&
518
+ ((ry > 0 && startY > cy - ry && startY < cy + ry) ||
519
+ (ry < 0 && startY < cy - ry && startY > cy + ry))
520
+ ) {
521
+ ctx.zone = 'CENTER';
522
+ } else {
523
+ ctx.zone = 'OUT';
524
+ initialItem.value = null;
722
525
  }
723
- } else {
724
- currentItem.value = {
725
- type: currentItem.value.type,
726
- strokeWidth: currentItem.value.strokeWidth,
727
- color: currentItem.value.color,
728
- data: {
729
- cx: startX + translationX,
730
- cy: startY + translationY,
731
- rx: translationX,
732
- ry: translationY,
733
- },
734
- };
735
- }
736
-
737
- break;
738
- case 'rectangle':
739
- if (initialItem.value?.type === currentItem.value.type) {
740
- const height =
741
- typeof initialItem.value?.data.height === 'string'
742
- ? parseFloat(initialItem.value?.data.height)
743
- : initialItem.value?.data.height || 0;
744
-
745
- const width =
746
- typeof initialItem.value?.data.width === 'string'
747
- ? parseFloat(initialItem.value?.data.width)
748
- : initialItem.value?.data.width || 0;
749
526
 
527
+ break;
528
+ case 'rectangle':
750
529
  const x =
751
- typeof initialItem.value?.data.x === 'string'
752
- ? parseFloat(initialItem.value?.data.x)
753
- : initialItem.value?.data.x || 0;
754
-
530
+ typeof currentItem.value.data.x === 'string'
531
+ ? parseFloat(currentItem.value.data.x)
532
+ : currentItem.value.data.x || 0;
755
533
  const y =
756
- typeof initialItem.value?.data.y === 'string'
757
- ? parseFloat(initialItem.value?.data.y)
758
- : initialItem.value?.data.y || 0;
759
-
760
- switch (zone) {
761
- case 'TOP_LEFT':
762
- currentItem.value = {
763
- type: 'rectangle',
764
- strokeWidth: currentItem.value.strokeWidth,
765
- color: currentItem.value.color,
766
- data: {
767
- x: startX + translationX,
768
- y: startY + translationY,
769
- width: width - translationX,
770
- height: height - translationY,
771
- },
772
- };
773
- break;
774
- case 'TOP_RIGHT':
775
- currentItem.value = {
776
- type: 'rectangle',
777
- strokeWidth: currentItem.value.strokeWidth,
778
- color: currentItem.value.color,
779
- data: {
780
- x: x,
781
- y: startY + translationY,
782
- width: width + translationX,
783
- height: height - translationY,
784
- },
785
- };
786
- break;
787
- case 'BOTTOM_LEFT':
788
- currentItem.value = {
789
- type: 'rectangle',
790
- strokeWidth: currentItem.value.strokeWidth,
791
- color: currentItem.value.color,
792
- data: {
793
- x: startX + translationX,
794
- y: y,
795
- width: width - translationX,
796
- height: height + translationY,
797
- },
798
- };
799
- break;
800
- case 'BOTTOM_RIGHT':
801
- currentItem.value = {
802
- type: 'rectangle',
803
- strokeWidth: currentItem.value.strokeWidth,
804
- color: currentItem.value.color,
805
- data: {
806
- x: x,
807
- y: y,
808
- width: width + translationX,
809
- height: height + translationY,
810
- },
811
- };
812
- break;
813
- case 'CENTER':
814
- currentItem.value = {
815
- type: 'rectangle',
816
- strokeWidth: currentItem.value.strokeWidth,
817
- color: currentItem.value.color,
818
- data: {
819
- x: x + translationX,
820
- y: y + translationY,
821
- width: width,
822
- height: height,
823
- },
824
- };
825
- break;
534
+ typeof currentItem.value.data.y === 'string'
535
+ ? parseFloat(currentItem.value.data.y)
536
+ : currentItem.value.data.y || 0;
537
+ const height =
538
+ typeof currentItem.value.data.height === 'string'
539
+ ? parseFloat(currentItem.value.data.height)
540
+ : currentItem.value.data.height || 0;
541
+ const width =
542
+ typeof currentItem.value.data.width === 'string'
543
+ ? parseFloat(currentItem.value.data.width)
544
+ : currentItem.value.data.width || 0;
545
+
546
+ if (startX <= x + THRESHOLD && startX >= x - THRESHOLD) {
547
+ if (startY <= y + THRESHOLD && startY >= y - THRESHOLD) {
548
+ ctx.zone = 'TOP_LEFT';
549
+ } else if (
550
+ startY <= y + height + THRESHOLD &&
551
+ startY >= y + height - THRESHOLD
552
+ ) {
553
+ ctx.zone = 'BOTTOM_LEFT';
554
+ }
555
+ } else if (
556
+ startX <= x + width + THRESHOLD &&
557
+ startX >= x + width - THRESHOLD
558
+ ) {
559
+ if (startY <= y + THRESHOLD && startY >= y - THRESHOLD) {
560
+ ctx.zone = 'TOP_RIGHT';
561
+ } else if (
562
+ startY <= y + height + THRESHOLD &&
563
+ startY >= y + height - THRESHOLD
564
+ ) {
565
+ ctx.zone = 'BOTTOM_RIGHT';
566
+ }
567
+ } else if (
568
+ ((width > 0 && startX > x && startX < x + width) ||
569
+ (width < 0 && startX < x && startX > x + width)) &&
570
+ ((height > 0 && startY > y && startY < y + height) ||
571
+ (height < 0 && startY < y && startY > y + height))
572
+ ) {
573
+ ctx.zone = 'CENTER';
574
+ } else {
575
+ ctx.zone = 'OUT';
576
+ initialItem.value = null;
826
577
  }
827
- } else {
828
- currentItem.value = {
829
- type: 'rectangle',
830
- strokeWidth: currentItem.value.strokeWidth,
831
- color: currentItem.value.color,
832
- data: {
833
- x: currentItem.value.data.x,
834
- y: currentItem.value.data.y,
835
- width: translationX,
836
- height: translationY,
837
- },
838
- };
839
- }
840
- break;
841
- case 'singleHead':
842
- case 'doubleHead':
843
- if (initialItem.value?.type === currentItem.value.type) {
844
- const x1 =
845
- typeof initialItem.value?.data.x1 === 'string'
846
- ? parseFloat(initialItem.value?.data.x1)
847
- : initialItem.value?.data.x1 || 0;
848
578
 
579
+ break;
580
+ case 'doubleHead':
581
+ case 'singleHead':
582
+ const x1 =
583
+ typeof currentItem.value.data.x1 === 'string'
584
+ ? parseFloat(currentItem.value.data.x1)
585
+ : currentItem.value.data.x1 || 0;
849
586
  const y1 =
850
- typeof initialItem.value?.data.y1 === 'string'
851
- ? parseFloat(initialItem.value?.data.y1)
852
- : initialItem.value?.data.y1 || 0;
853
-
587
+ typeof currentItem.value.data.y1 === 'string'
588
+ ? parseFloat(currentItem.value.data.y1)
589
+ : currentItem.value.data.y1 || 0;
854
590
  const x2 =
855
- typeof initialItem.value?.data.x2 === 'string'
856
- ? parseFloat(initialItem.value?.data.x2)
857
- : initialItem.value?.data.x2 || 0;
858
-
591
+ typeof currentItem.value.data.x2 === 'string'
592
+ ? parseFloat(currentItem.value.data.x2)
593
+ : currentItem.value.data.x2 || 0;
859
594
  const y2 =
860
- typeof initialItem.value?.data.y2 === 'string'
861
- ? parseFloat(initialItem.value?.data.y2)
862
- : initialItem.value?.data.y2 || 0;
863
-
864
- switch (zone) {
865
- case 'TOP':
866
- currentItem.value = {
867
- type: currentItem.value.type,
868
- strokeWidth: currentItem.value.strokeWidth,
869
- color: currentItem.value.color,
870
- data: {
871
- x1: x1 + translationX,
872
- y1: y1 + translationY,
873
- x2: x2,
874
- y2: y2,
875
- },
876
- };
877
- break;
878
- case 'BOTTOM':
879
- currentItem.value = {
880
- type: currentItem.value.type,
881
- strokeWidth: currentItem.value.strokeWidth,
882
- color: currentItem.value.color,
883
- data: {
884
- x1: x1,
885
- y1: y1,
886
- x2: x2 + translationX,
887
- y2: y2 + translationY,
888
- },
889
- };
890
- break;
891
- case 'CENTER':
892
- currentItem.value = {
893
- type: currentItem.value.type,
894
- strokeWidth: currentItem.value.strokeWidth,
895
- color: currentItem.value.color,
896
- data: {
897
- x1: x1 + translationX,
898
- y1: y1 + translationY,
899
- x2: x2 + translationX,
900
- y2: y2 + translationY,
901
- },
902
- };
903
- break;
595
+ typeof currentItem.value.data.y2 === 'string'
596
+ ? parseFloat(currentItem.value.data.y2)
597
+ : currentItem.value.data.y2 || 0;
598
+
599
+ if (
600
+ startX <= x1 + THRESHOLD &&
601
+ startX >= x1 - THRESHOLD &&
602
+ startY <= y1 + THRESHOLD &&
603
+ startY >= y1 - THRESHOLD
604
+ ) {
605
+ ctx.zone = 'TOP';
606
+ } else if (
607
+ startX <= x2 + THRESHOLD &&
608
+ startX >= x2 - THRESHOLD &&
609
+ startY - THRESHOLD <= y2 + THRESHOLD &&
610
+ startY + THRESHOLD >= y2 - THRESHOLD
611
+ ) {
612
+ ctx.zone = 'BOTTOM';
613
+ } else if (
614
+ pDistance({ x: startX, y: startY }, { x1, x2, y1, y2 }) <=
615
+ THRESHOLD &&
616
+ ((startX > x1 && startX < x2) ||
617
+ (startX < x1 && startX > x2)) &&
618
+ ((startY > y1 && startY < y2) || (startY < y1 && startY > y2))
619
+ ) {
620
+ ctx.zone = 'CENTER';
621
+ } else {
622
+ ctx.zone = 'OUT';
623
+ initialItem.value = null;
904
624
  }
905
- } else {
906
- currentItem.value = {
907
- type: currentItem.value.type,
908
- strokeWidth: currentItem.value.strokeWidth,
909
- color: currentItem.value.color,
910
- data: {
911
- x1: startX,
912
- y1: startY,
913
- x2: startX + translationX,
914
- y2: startY + translationY,
915
- },
916
- };
917
- }
918
- break;
919
- case 'text':
920
- if (initialItem.value?.type === currentItem.value.type) {
625
+
626
+ break;
627
+ case 'text':
921
628
  const xText =
922
- typeof initialItem.value?.data.x === 'string'
923
- ? parseFloat(initialItem.value?.data.x)
924
- : initialItem.value?.data.x || 0;
629
+ typeof currentItem.value.data.x === 'string'
630
+ ? parseFloat(currentItem.value.data.x)
631
+ : currentItem.value.data.x || 0;
925
632
  const yText =
926
- typeof initialItem.value?.data.y === 'string'
927
- ? parseFloat(initialItem.value?.data.y)
928
- : initialItem.value?.data.y || 0;
633
+ typeof currentItem.value.data.y === 'string'
634
+ ? parseFloat(currentItem.value.data.y)
635
+ : currentItem.value.data.y || 0;
929
636
  const widthText =
930
- typeof initialItem.value?.data.width === 'string'
931
- ? parseFloat(initialItem.value?.data.width)
932
- : initialItem.value?.data.width || 0;
637
+ typeof currentItem.value.data.width === 'string'
638
+ ? parseFloat(currentItem.value.data.width)
639
+ : currentItem.value.data.width || 0;
933
640
  const heightText =
934
- typeof initialItem.value?.data.height === 'string'
935
- ? parseFloat(initialItem.value?.data.height)
936
- : initialItem.value?.data.height || 0;
937
-
938
- switch (zone) {
939
- case 'LEFT':
940
- currentItem.value = {
941
- type: currentItem.value.type,
942
- strokeWidth: currentItem.value.strokeWidth,
943
- color: currentItem.value.color,
944
- text: currentItem.value.text,
945
- data: {
946
- x: xText + translationX,
947
- y: yText,
948
- width: widthText - translationX,
949
- height: heightText,
950
- },
951
- };
952
- break;
953
- case 'RIGHT':
954
- currentItem.value = {
955
- type: currentItem.value.type,
956
- strokeWidth: currentItem.value.strokeWidth,
957
- color: currentItem.value.color,
958
- text: currentItem.value.text,
959
- data: {
960
- x: xText,
961
- y: yText,
962
- width: widthText + translationX,
963
- height: heightText,
964
- },
965
- };
966
- break;
967
- case 'CENTER':
968
- currentItem.value = {
969
- type: currentItem.value.type,
970
- strokeWidth: currentItem.value.strokeWidth,
971
- color: currentItem.value.color,
972
- text: currentItem.value.text,
973
- data: {
974
- x: xText + translationX,
975
- y: yText + translationY,
976
- width: widthText,
977
- height: heightText,
978
- },
979
- };
980
- break;
641
+ typeof currentItem.value.data.height === 'string'
642
+ ? parseFloat(currentItem.value.data.height)
643
+ : currentItem.value.data.height || 0;
644
+
645
+ if (
646
+ startX <= xText + THRESHOLD &&
647
+ startX >= xText - THRESHOLD &&
648
+ startY <= yText + heightText / 2 + THRESHOLD &&
649
+ startY >= yText + heightText / 2 - THRESHOLD
650
+ ) {
651
+ ctx.zone = 'LEFT';
652
+ } else if (
653
+ startX <= xText + widthText + THRESHOLD &&
654
+ startX >= xText + widthText - THRESHOLD &&
655
+ startY <= yText + heightText / 2 + THRESHOLD &&
656
+ startY >= yText + heightText / 2 - THRESHOLD
657
+ ) {
658
+ ctx.zone = 'RIGHT';
659
+ } else if (
660
+ ((widthText > 0 &&
661
+ startX > xText &&
662
+ startX < xText + widthText) ||
663
+ (widthText < 0 &&
664
+ startX < xText &&
665
+ startX > xText + widthText)) &&
666
+ ((heightText > 0 &&
667
+ startY > yText &&
668
+ startY < yText + heightText) ||
669
+ (heightText < 0 &&
670
+ startY < yText &&
671
+ startY > yText + heightText))
672
+ ) {
673
+ ctx.zone = 'CENTER';
674
+ } else {
675
+ ctx.zone = 'OUT';
676
+ initialItem.value = null;
981
677
  }
982
- } else {
983
- currentItem.value = {
984
- type: currentItem.value.type,
985
- strokeWidth: currentItem.value.strokeWidth,
986
- color: currentItem.value.color,
987
- text: currentItem.value.text,
988
- data: {
989
- x: startX + translationX,
990
- y: startY + translationY,
991
- width: currentItem.value.data.width,
992
- height: currentItem.value.data.height,
993
- },
994
- };
678
+
679
+ break;
680
+ case 'pen':
681
+ if (
682
+ currentItem.value.data.some(
683
+ (p) =>
684
+ startX <= p.x + THRESHOLD &&
685
+ startX >= p.x - THRESHOLD &&
686
+ startY <= p.y + THRESHOLD &&
687
+ startY >= p.y - THRESHOLD
688
+ )
689
+ ) {
690
+ ctx.zone = 'CENTER';
691
+ } else {
692
+ ctx.zone = 'OUT';
693
+ initialItem.value = null;
694
+ }
695
+ break;
696
+ default:
697
+ ctx.zone = 'OUT';
698
+ initialItem.value = null;
699
+ break;
700
+ }
701
+ },
702
+ onActive: (
703
+ { x: currentX, y: currentY, translationX, translationY },
704
+ ctx
705
+ ) => {
706
+ const { startX, startY, zone, newlyCreated } = ctx;
707
+ if (zone === 'OUT' && newlyCreated === false) {
708
+ ctx.newlyCreated = true;
709
+ if (mode.value === 'text') {
710
+ runOnJS(setTextVal)('');
995
711
  }
996
- }
997
- },
998
- onEnd: (_event) => {
999
- panPosition.value = withTiming(0);
1000
-
1001
- if (currentItem.value?.type === 'text') {
1002
- runOnJS(textFocus)();
1003
-
1004
- currentItem.value = {
1005
- type: currentItem.value.type,
1006
- strokeWidth: currentItem.value.strokeWidth,
1007
- color: currentItem.value.color,
1008
- data: currentItem.value.data,
1009
- text:
1010
- currentItem.value.text !== DEFAULT_TEXT
1011
- ? currentItem.value.text ?? ''
1012
- : '',
1013
- };
1014
- }
1015
- },
1016
- },
1017
- []
1018
- );
712
+ drawNewItem(
713
+ mode,
714
+ currentItem,
715
+ addDoneItem,
716
+ { x: startX, y: startY },
717
+ { textBaseHeight, strokeWidth, color }
718
+ );
719
+ onSelectionChange && runOnJS(onSelectionChange)(true);
720
+ onCancelChange && runOnJS(onCancelChange)(true);
721
+ }
722
+ switch (currentItem.value?.type) {
723
+ case 'pen':
724
+ if (
725
+ initialItem.value?.type === currentItem.value.type &&
726
+ zone === 'CENTER'
727
+ ) {
728
+ currentItem.value = {
729
+ type: 'pen',
730
+ strokeWidth: currentItem.value.strokeWidth,
731
+ color: currentItem.value.color,
732
+ data: initialItem.value.data.map((p) => ({
733
+ x: p.x + translationX,
734
+ y: p.y + translationY,
735
+ })),
736
+ };
737
+ } else {
738
+ currentItem.value = {
739
+ type: 'pen',
740
+ strokeWidth: currentItem.value.strokeWidth,
741
+ color: currentItem.value.color,
742
+ data: currentItem.value.data.concat({
743
+ x: currentX,
744
+ y: currentY,
745
+ }),
746
+ };
747
+ }
748
+ break;
749
+ case 'ellipse':
750
+ if (initialItem.value?.type === currentItem.value.type) {
751
+ const rx =
752
+ typeof initialItem.value.data.rx === 'string'
753
+ ? parseFloat(initialItem.value?.data.rx)
754
+ : initialItem.value.data.rx || 0;
755
+
756
+ const ry =
757
+ typeof initialItem.value.data.ry === 'string'
758
+ ? parseFloat(initialItem.value.data.ry)
759
+ : initialItem.value.data.ry || 0;
760
+
761
+ const cx =
762
+ typeof initialItem.value.data.cx === 'string'
763
+ ? parseFloat(initialItem.value.data.cx)
764
+ : initialItem.value.data.cx || 0;
765
+
766
+ const cy =
767
+ typeof initialItem.value.data.cy === 'string'
768
+ ? parseFloat(initialItem.value.data.cy)
769
+ : initialItem.value.data.cy || 0;
770
+
771
+ switch (zone) {
772
+ case 'TOP':
773
+ currentItem.value = {
774
+ type: currentItem.value.type,
775
+ strokeWidth: currentItem.value.strokeWidth,
776
+ color: currentItem.value.color,
777
+ data: {
778
+ cx: cx,
779
+ cy: cy + translationY,
780
+ rx: rx,
781
+ ry: ry - translationY,
782
+ },
783
+ };
784
+ break;
785
+ case 'BOTTOM':
786
+ currentItem.value = {
787
+ type: currentItem.value.type,
788
+ strokeWidth: currentItem.value.strokeWidth,
789
+ color: currentItem.value.color,
790
+ data: {
791
+ cx: cx,
792
+ cy: cy + translationY,
793
+ rx: rx,
794
+ ry: ry + translationY,
795
+ },
796
+ };
797
+ break;
798
+ case 'LEFT':
799
+ currentItem.value = {
800
+ type: currentItem.value.type,
801
+ strokeWidth: currentItem.value.strokeWidth,
802
+ color: currentItem.value.color,
803
+ data: {
804
+ cx: cx + translationX,
805
+ cy: cy,
806
+ rx: rx - translationX,
807
+ ry: ry,
808
+ },
809
+ };
810
+ break;
811
+ case 'RIGHT':
812
+ currentItem.value = {
813
+ type: currentItem.value.type,
814
+ strokeWidth: currentItem.value.strokeWidth,
815
+ color: currentItem.value.color,
816
+ data: {
817
+ cx: cx + translationX,
818
+ cy: cy,
819
+ rx: rx + translationX,
820
+ ry: ry,
821
+ },
822
+ };
823
+ break;
824
+ case 'CENTER':
825
+ currentItem.value = {
826
+ type: currentItem.value.type,
827
+ strokeWidth: currentItem.value.strokeWidth,
828
+ color: currentItem.value.color,
829
+ data: {
830
+ cx: cx + translationX,
831
+ cy: cy + translationY,
832
+ rx: rx,
833
+ ry: ry,
834
+ },
835
+ };
836
+ break;
837
+ }
838
+ } else {
839
+ currentItem.value = {
840
+ type: currentItem.value.type,
841
+ strokeWidth: currentItem.value.strokeWidth,
842
+ color: currentItem.value.color,
843
+ data: {
844
+ cx: startX + translationX,
845
+ cy: startY + translationY,
846
+ rx: translationX,
847
+ ry: translationY,
848
+ },
849
+ };
850
+ }
1019
851
 
1020
- const rightPaneStyle = useAnimatedStyle(() => {
1021
- return {
1022
- transform: [{ translateX: panPosition.value }],
1023
- };
1024
- }, [panPosition.value]);
852
+ break;
853
+ case 'rectangle':
854
+ if (initialItem.value?.type === currentItem.value.type) {
855
+ const height =
856
+ typeof initialItem.value?.data.height === 'string'
857
+ ? parseFloat(initialItem.value?.data.height)
858
+ : initialItem.value?.data.height || 0;
859
+
860
+ const width =
861
+ typeof initialItem.value?.data.width === 'string'
862
+ ? parseFloat(initialItem.value?.data.width)
863
+ : initialItem.value?.data.width || 0;
864
+
865
+ const x =
866
+ typeof initialItem.value?.data.x === 'string'
867
+ ? parseFloat(initialItem.value?.data.x)
868
+ : initialItem.value?.data.x || 0;
869
+
870
+ const y =
871
+ typeof initialItem.value?.data.y === 'string'
872
+ ? parseFloat(initialItem.value?.data.y)
873
+ : initialItem.value?.data.y || 0;
874
+
875
+ switch (zone) {
876
+ case 'TOP_LEFT':
877
+ currentItem.value = {
878
+ type: 'rectangle',
879
+ strokeWidth: currentItem.value.strokeWidth,
880
+ color: currentItem.value.color,
881
+ data: {
882
+ x: startX + translationX,
883
+ y: startY + translationY,
884
+ width: width - translationX,
885
+ height: height - translationY,
886
+ },
887
+ };
888
+ break;
889
+ case 'TOP_RIGHT':
890
+ currentItem.value = {
891
+ type: 'rectangle',
892
+ strokeWidth: currentItem.value.strokeWidth,
893
+ color: currentItem.value.color,
894
+ data: {
895
+ x: x,
896
+ y: startY + translationY,
897
+ width: width + translationX,
898
+ height: height - translationY,
899
+ },
900
+ };
901
+ break;
902
+ case 'BOTTOM_LEFT':
903
+ currentItem.value = {
904
+ type: 'rectangle',
905
+ strokeWidth: currentItem.value.strokeWidth,
906
+ color: currentItem.value.color,
907
+ data: {
908
+ x: startX + translationX,
909
+ y: y,
910
+ width: width - translationX,
911
+ height: height + translationY,
912
+ },
913
+ };
914
+ break;
915
+ case 'BOTTOM_RIGHT':
916
+ currentItem.value = {
917
+ type: 'rectangle',
918
+ strokeWidth: currentItem.value.strokeWidth,
919
+ color: currentItem.value.color,
920
+ data: {
921
+ x: x,
922
+ y: y,
923
+ width: width + translationX,
924
+ height: height + translationY,
925
+ },
926
+ };
927
+ break;
928
+ case 'CENTER':
929
+ currentItem.value = {
930
+ type: 'rectangle',
931
+ strokeWidth: currentItem.value.strokeWidth,
932
+ color: currentItem.value.color,
933
+ data: {
934
+ x: x + translationX,
935
+ y: y + translationY,
936
+ width: width,
937
+ height: height,
938
+ },
939
+ };
940
+ break;
941
+ }
942
+ } else {
943
+ currentItem.value = {
944
+ type: 'rectangle',
945
+ strokeWidth: currentItem.value.strokeWidth,
946
+ color: currentItem.value.color,
947
+ data: {
948
+ x: currentItem.value.data.x,
949
+ y: currentItem.value.data.y,
950
+ width: translationX,
951
+ height: translationY,
952
+ },
953
+ };
954
+ }
955
+ break;
956
+ case 'singleHead':
957
+ case 'doubleHead':
958
+ if (initialItem.value?.type === currentItem.value.type) {
959
+ const x1 =
960
+ typeof initialItem.value?.data.x1 === 'string'
961
+ ? parseFloat(initialItem.value?.data.x1)
962
+ : initialItem.value?.data.x1 || 0;
963
+
964
+ const y1 =
965
+ typeof initialItem.value?.data.y1 === 'string'
966
+ ? parseFloat(initialItem.value?.data.y1)
967
+ : initialItem.value?.data.y1 || 0;
968
+
969
+ const x2 =
970
+ typeof initialItem.value?.data.x2 === 'string'
971
+ ? parseFloat(initialItem.value?.data.x2)
972
+ : initialItem.value?.data.x2 || 0;
973
+
974
+ const y2 =
975
+ typeof initialItem.value?.data.y2 === 'string'
976
+ ? parseFloat(initialItem.value?.data.y2)
977
+ : initialItem.value?.data.y2 || 0;
978
+
979
+ switch (zone) {
980
+ case 'TOP':
981
+ currentItem.value = {
982
+ type: currentItem.value.type,
983
+ strokeWidth: currentItem.value.strokeWidth,
984
+ color: currentItem.value.color,
985
+ data: {
986
+ x1: x1 + translationX,
987
+ y1: y1 + translationY,
988
+ x2: x2,
989
+ y2: y2,
990
+ },
991
+ };
992
+ break;
993
+ case 'BOTTOM':
994
+ currentItem.value = {
995
+ type: currentItem.value.type,
996
+ strokeWidth: currentItem.value.strokeWidth,
997
+ color: currentItem.value.color,
998
+ data: {
999
+ x1: x1,
1000
+ y1: y1,
1001
+ x2: x2 + translationX,
1002
+ y2: y2 + translationY,
1003
+ },
1004
+ };
1005
+ break;
1006
+ case 'CENTER':
1007
+ currentItem.value = {
1008
+ type: currentItem.value.type,
1009
+ strokeWidth: currentItem.value.strokeWidth,
1010
+ color: currentItem.value.color,
1011
+ data: {
1012
+ x1: x1 + translationX,
1013
+ y1: y1 + translationY,
1014
+ x2: x2 + translationX,
1015
+ y2: y2 + translationY,
1016
+ },
1017
+ };
1018
+ break;
1019
+ }
1020
+ } else {
1021
+ currentItem.value = {
1022
+ type: currentItem.value.type,
1023
+ strokeWidth: currentItem.value.strokeWidth,
1024
+ color: currentItem.value.color,
1025
+ data: {
1026
+ x1: startX,
1027
+ y1: startY,
1028
+ x2: startX + translationX,
1029
+ y2: startY + translationY,
1030
+ },
1031
+ };
1032
+ }
1033
+ break;
1034
+ case 'text':
1035
+ if (initialItem.value?.type === currentItem.value.type) {
1036
+ const xText =
1037
+ typeof initialItem.value?.data.x === 'string'
1038
+ ? parseFloat(initialItem.value?.data.x)
1039
+ : initialItem.value?.data.x || 0;
1040
+ const yText =
1041
+ typeof initialItem.value?.data.y === 'string'
1042
+ ? parseFloat(initialItem.value?.data.y)
1043
+ : initialItem.value?.data.y || 0;
1044
+ const widthText =
1045
+ typeof initialItem.value?.data.width === 'string'
1046
+ ? parseFloat(initialItem.value?.data.width)
1047
+ : initialItem.value?.data.width || 0;
1048
+ const heightText =
1049
+ typeof initialItem.value?.data.height === 'string'
1050
+ ? parseFloat(initialItem.value?.data.height)
1051
+ : initialItem.value?.data.height || 0;
1052
+
1053
+ switch (zone) {
1054
+ case 'LEFT':
1055
+ currentItem.value = {
1056
+ type: currentItem.value.type,
1057
+ strokeWidth: currentItem.value.strokeWidth,
1058
+ color: currentItem.value.color,
1059
+ text: currentItem.value.text,
1060
+ data: {
1061
+ x: xText + translationX,
1062
+ y: yText,
1063
+ width: widthText - translationX,
1064
+ height: heightText,
1065
+ },
1066
+ };
1067
+ break;
1068
+ case 'RIGHT':
1069
+ currentItem.value = {
1070
+ type: currentItem.value.type,
1071
+ strokeWidth: currentItem.value.strokeWidth,
1072
+ color: currentItem.value.color,
1073
+ text: currentItem.value.text,
1074
+ data: {
1075
+ x: xText,
1076
+ y: yText,
1077
+ width: widthText + translationX,
1078
+ height: heightText,
1079
+ },
1080
+ };
1081
+ break;
1082
+ case 'CENTER':
1083
+ currentItem.value = {
1084
+ type: currentItem.value.type,
1085
+ strokeWidth: currentItem.value.strokeWidth,
1086
+ color: currentItem.value.color,
1087
+ text: currentItem.value.text,
1088
+ data: {
1089
+ x: xText + translationX,
1090
+ y: yText + translationY,
1091
+ width: widthText,
1092
+ height: heightText,
1093
+ },
1094
+ };
1095
+ break;
1096
+ }
1097
+ } else {
1098
+ currentItem.value = {
1099
+ type: currentItem.value.type,
1100
+ strokeWidth: currentItem.value.strokeWidth,
1101
+ color: currentItem.value.color,
1102
+ text: currentItem.value.text,
1103
+ data: {
1104
+ x: startX + translationX,
1105
+ y: startY + translationY,
1106
+ width: currentItem.value.data.width,
1107
+ height: currentItem.value.data.height,
1108
+ },
1109
+ };
1110
+ }
1111
+ }
1112
+ },
1113
+ onEnd: (_event) => {
1114
+ panPosition.value = withTiming(0);
1115
+
1116
+ if (currentItem.value?.type === 'text') {
1117
+ runOnJS(textFocus)();
1118
+
1119
+ currentItem.value = {
1120
+ type: currentItem.value.type,
1121
+ strokeWidth: currentItem.value.strokeWidth,
1122
+ color: currentItem.value.color,
1123
+ data: currentItem.value.data,
1124
+ text:
1125
+ currentItem.value.text !== DEFAULT_TEXT
1126
+ ? currentItem.value.text ?? ''
1127
+ : '',
1128
+ };
1129
+ }
1025
1130
 
1026
- useEffect(() => {
1027
- const sudDidHide = Keyboard.addListener('keyboardDidHide', () => {
1028
- showTextInput.value = false;
1029
- });
1131
+ runOnJS(addScreenStates)(currentItem.value);
1132
+ },
1133
+ },
1134
+ []
1135
+ );
1030
1136
 
1031
- const sudDidShow = Keyboard.addListener('keyboardDidShow', (event) => {
1032
- // avoid events triggered by InputAccessoryView
1033
- if (event.endCoordinates.height > 100) {
1034
- showTextInput.value = true;
1035
- }
1137
+ const rightPaneStyle = useAnimatedStyle(() => {
1138
+ return {
1139
+ transform: [{ translateX: panPosition.value }],
1140
+ };
1036
1141
  });
1037
1142
 
1038
- // cleanup function
1039
- return () => {
1040
- sudDidShow.remove();
1041
- sudDidHide.remove();
1042
- };
1043
- }, [showTextInput]);
1143
+ useEffect(() => {
1144
+ const sudDidHide = Keyboard.addListener('keyboardDidHide', () => {
1145
+ showTextInput.value = false;
1146
+ });
1044
1147
 
1045
- const textInputRef = useRef<TextInput>(null);
1148
+ const sudDidShow = Keyboard.addListener('keyboardDidShow', (event) => {
1149
+ // avoid events triggered by InputAccessoryView
1150
+ if (event.endCoordinates.height > 100) {
1151
+ showTextInput.value = true;
1152
+ }
1153
+ });
1046
1154
 
1047
- const textInputContainerStyle = useAnimatedStyle(() => {
1048
- return {
1049
- height: 'auto',
1050
- backgroundColor: 'white',
1051
- display: 'flex',
1052
- opacity: showTextInput.value ? withTiming(1) : withTiming(0),
1053
- };
1054
- }, [showTextInput.value]);
1155
+ // cleanup function
1156
+ return () => {
1157
+ sudDidShow.remove();
1158
+ sudDidHide.remove();
1159
+ };
1160
+ }, [showTextInput]);
1055
1161
 
1056
- const textInputStyle = useAnimatedStyle(() => {
1057
- return {
1058
- display: showTextInput.value ? 'flex' : 'none',
1059
- opacity: showTextInput.value ? withTiming(1) : withTiming(0),
1060
- };
1061
- }, [showTextInput.value]);
1062
-
1063
- useAnimatedReaction(
1064
- () => {
1065
- return { strokeWidth: strokeWidth.value, color: color.value };
1066
- },
1067
- ({ strokeWidth, color }: { strokeWidth: number; color: hslColor }) => {
1068
- switch (currentItem.value?.type) {
1069
- case 'singleHead':
1070
- currentItem.value = {
1071
- type: currentItem.value.type,
1072
- data: currentItem.value.data,
1073
- strokeWidth,
1074
- color,
1075
- };
1076
- break;
1077
- case 'doubleHead':
1078
- currentItem.value = {
1079
- type: currentItem.value.type,
1080
- data: currentItem.value.data,
1081
- strokeWidth,
1082
- color,
1083
- };
1084
- break;
1085
- case 'ellipse':
1086
- currentItem.value = {
1087
- type: currentItem.value.type,
1088
- data: currentItem.value.data,
1089
- strokeWidth,
1090
- color,
1091
- };
1092
- break;
1093
- case 'rectangle':
1094
- currentItem.value = {
1095
- type: currentItem.value.type,
1096
- data: currentItem.value.data,
1097
- strokeWidth,
1098
- color,
1099
- };
1100
- break;
1101
-
1102
- case 'pen':
1103
- currentItem.value = {
1104
- type: currentItem.value.type,
1105
- data: currentItem.value.data,
1106
- strokeWidth,
1107
- color,
1108
- };
1109
- break;
1110
- case 'text':
1111
- currentItem.value = {
1112
- type: currentItem.value.type,
1113
- data: currentItem.value.data,
1114
- strokeWidth,
1115
- color,
1116
- text: currentItem.value.text,
1117
- };
1118
- break;
1119
- }
1120
- },
1121
- [strokeWidth.value, color.value]
1122
- );
1162
+ const textInputRef = useRef<TextInput>(null);
1163
+
1164
+ const textInputContainerStyle = useAnimatedStyle(() => {
1165
+ return {
1166
+ height: 'auto',
1167
+ backgroundColor: 'white',
1168
+ display: 'flex',
1169
+ opacity: showTextInput.value ? withTiming(1) : withTiming(0),
1170
+ };
1171
+ }, [showTextInput.value]);
1172
+
1173
+ const textInputStyle = useAnimatedStyle(() => {
1174
+ return {
1175
+ display: showTextInput.value ? 'flex' : 'none',
1176
+ opacity: showTextInput.value ? withTiming(1) : withTiming(0),
1177
+ };
1178
+ }, [showTextInput.value]);
1179
+
1180
+ useAnimatedReaction(
1181
+ () => {
1182
+ return {
1183
+ strokeWidth: strokeWidth.value,
1184
+ color: color.value,
1185
+ };
1186
+ },
1187
+ ({
1188
+ strokeWidth: sw,
1189
+ color: c,
1190
+ }: {
1191
+ strokeWidth: number;
1192
+ color: hslColor;
1193
+ }) => {
1194
+ switch (currentItem.value?.type) {
1195
+ case 'singleHead':
1196
+ currentItem.value = {
1197
+ type: currentItem.value.type,
1198
+ data: currentItem.value.data,
1199
+ strokeWidth: sw,
1200
+ color: c,
1201
+ };
1202
+ break;
1203
+ case 'doubleHead':
1204
+ currentItem.value = {
1205
+ type: currentItem.value.type,
1206
+ data: currentItem.value.data,
1207
+ strokeWidth: sw,
1208
+ color: c,
1209
+ };
1210
+ break;
1211
+ case 'ellipse':
1212
+ currentItem.value = {
1213
+ type: currentItem.value.type,
1214
+ data: currentItem.value.data,
1215
+ strokeWidth: sw,
1216
+ color: c,
1217
+ };
1218
+ break;
1219
+ case 'rectangle':
1220
+ currentItem.value = {
1221
+ type: currentItem.value.type,
1222
+ data: currentItem.value.data,
1223
+ strokeWidth: sw,
1224
+ color: c,
1225
+ };
1226
+ break;
1123
1227
 
1124
- const onPressItem = useCallback(
1125
- (item: DrawItem, index: number) => () => {
1126
- onSelectionChange?.(true);
1228
+ case 'pen':
1229
+ currentItem.value = {
1230
+ type: currentItem.value.type,
1231
+ data: currentItem.value.data,
1232
+ strokeWidth: sw,
1233
+ color: c,
1234
+ };
1235
+ break;
1236
+ case 'text':
1237
+ currentItem.value = {
1238
+ type: currentItem.value.type,
1239
+ data: currentItem.value.data,
1240
+ strokeWidth: sw,
1241
+ color: c,
1242
+ text: currentItem.value.text,
1243
+ };
1244
+ break;
1245
+ }
1246
+ },
1247
+ [strokeWidth.value, color.value]
1248
+ );
1127
1249
 
1128
- const previousItem = currentItem.value;
1250
+ const onPressItem = useCallback(
1251
+ (item: DrawItem, index: number) => () => {
1252
+ onSelectionChange?.(true);
1129
1253
 
1130
- strokeWidth.value = item.strokeWidth;
1131
- color.value = item.color;
1132
- currentItem.value = item;
1254
+ const previousItem = currentItem.value;
1133
1255
 
1134
- setDoneItems((done) => {
1135
- const copy = [...done];
1136
- copy.splice(index, 1);
1137
- return copy;
1138
- });
1256
+ strokeWidth.value = item.strokeWidth;
1257
+ color.value = item.color;
1258
+ currentItem.value = item;
1139
1259
 
1140
- if (previousItem) {
1141
- updateDoneItems(previousItem);
1142
- }
1260
+ deleteDoneItem(index);
1143
1261
 
1144
- if (item.type === 'text') {
1145
- setTextVal(item.text ?? '');
1146
- } else {
1147
- textInputRef.current?.blur();
1148
- }
1149
- },
1150
- [color, currentItem, strokeWidth, updateDoneItems, onSelectionChange]
1151
- );
1152
-
1153
- const onTextHeightChange = useCallback(
1154
- (height: number) => {
1155
- onTextHeightUpdate(currentItem, textBaseHeight, height);
1156
- },
1157
- [currentItem, textBaseHeight]
1158
- );
1159
-
1160
- const calculateSizes = useCallback(
1161
- (imageWidth: number, imageHeight: number) => {
1162
- if (drawRegion) {
1163
- setOriginalImageSize({ width: imageWidth, height: imageHeight });
1164
-
1165
- const ratioImageHeight =
1166
- Math.round(((imageHeight * drawRegion.width) / imageWidth) * 100) /
1167
- 100;
1168
-
1169
- if (ratioImageHeight < drawRegion.height) {
1170
- setImageSize({
1171
- width: drawRegion.width,
1172
- height: ratioImageHeight,
1173
- });
1262
+ if (previousItem) {
1263
+ addDoneItem(previousItem);
1264
+ }
1265
+
1266
+ if (item.type === 'text') {
1267
+ setTextVal(item.text ?? '');
1174
1268
  } else {
1175
- setImageSize({
1176
- height: drawRegion.height,
1177
- width:
1178
- Math.round(
1179
- ((imageWidth * drawRegion.height) / imageHeight) * 100
1180
- ) / 100,
1269
+ textInputRef.current?.blur();
1270
+ }
1271
+ },
1272
+ [
1273
+ onSelectionChange,
1274
+ currentItem,
1275
+ strokeWidth,
1276
+ color,
1277
+ deleteDoneItem,
1278
+ addDoneItem,
1279
+ ]
1280
+ );
1281
+
1282
+ const onTextHeightChange = useCallback(
1283
+ (height: number) => {
1284
+ onTextHeightUpdate(currentItem, textBaseHeight, height);
1285
+ },
1286
+ [currentItem, textBaseHeight]
1287
+ );
1288
+
1289
+ const calculateSizes = useCallback(
1290
+ (imageWidth: number, imageHeight: number) => {
1291
+ if (drawRegion) {
1292
+ setOriginalImageSize({ width: imageWidth, height: imageHeight });
1293
+
1294
+ const ratioImageHeight =
1295
+ Math.round(((imageHeight * drawRegion.width) / imageWidth) * 100) /
1296
+ 100;
1297
+
1298
+ if (ratioImageHeight < drawRegion.height) {
1299
+ setImageSize({
1300
+ width: drawRegion.width,
1301
+ height: ratioImageHeight,
1302
+ });
1303
+ } else {
1304
+ setImageSize({
1305
+ height: drawRegion.height,
1306
+ width:
1307
+ Math.round(
1308
+ ((imageWidth * drawRegion.height) / imageHeight) * 100
1309
+ ) / 100,
1310
+ });
1311
+ }
1312
+ }
1313
+ },
1314
+ [drawRegion]
1315
+ );
1316
+
1317
+ useEffect(() => {
1318
+ if (drawRegion && image) {
1319
+ if (typeof image === 'number') {
1320
+ const infos = Image.resolveAssetSource(image);
1321
+
1322
+ calculateSizes(infos.width, infos.height);
1323
+ } else if (image.uri) {
1324
+ Image.getSize(image.uri, (imageWidth, imageHeight) => {
1325
+ calculateSizes(imageWidth, imageHeight);
1181
1326
  });
1182
1327
  }
1183
1328
  }
1184
- },
1185
- [drawRegion]
1186
- );
1187
-
1188
- useEffect(() => {
1189
- if (drawRegion && image) {
1190
- if (typeof image === 'number') {
1191
- const infos = Image.resolveAssetSource(image);
1192
-
1193
- calculateSizes(infos.width, infos.height);
1194
- } else if (image.uri) {
1195
- Image.getSize(image.uri, (imageWidth, imageHeight) => {
1196
- calculateSizes(imageWidth, imageHeight);
1197
- });
1198
- }
1199
- }
1200
- }, [image, drawRegion, calculateSizes]);
1201
-
1202
- return (
1203
- <View style={styles.container}>
1204
- <View
1205
- style={styles.drawZone}
1206
- onLayout={(event) => {
1207
- setDrawRegion({
1208
- height: event.nativeEvent.layout.height,
1209
- width: event.nativeEvent.layout.width,
1210
- });
1211
- }}
1212
- >
1213
- <PanGestureHandler
1214
- activeOffsetX={2}
1215
- activeOffsetY={2}
1216
- onGestureEvent={onGestureEvent}
1329
+ }, [image, drawRegion, calculateSizes]);
1330
+
1331
+ return (
1332
+ <View style={styles.container}>
1333
+ <View
1334
+ style={styles.drawZone}
1335
+ onLayout={(event) => {
1336
+ setDrawRegion({
1337
+ height: event.nativeEvent.layout.height,
1338
+ width: event.nativeEvent.layout.width,
1339
+ });
1340
+ }}
1217
1341
  >
1218
- <Animated.View style={imageSize || drawRegion}>
1219
- <View ref={drawContainer}>
1220
- {image ? (
1221
- imageSize && originalImageSize ? (
1342
+ <PanGestureHandler onGestureEvent={onGestureEvent}>
1343
+ <Animated.View style={imageSize || drawRegion}>
1344
+ <View ref={drawContainer}>
1345
+ {image ? (
1346
+ imageSize && originalImageSize ? (
1347
+ <ViewShot
1348
+ ref={viewShot}
1349
+ options={{
1350
+ format: 'jpg',
1351
+ quality: 1,
1352
+ }}
1353
+ style={imageSize}
1354
+ >
1355
+ <ImageBackground source={image} style={styles.bgImage}>
1356
+ <DrawPad
1357
+ currentItem={currentItem}
1358
+ doneItems={drawStates.doneItems}
1359
+ onPressItem={onPressItem}
1360
+ onTextHeightChange={onTextHeightChange}
1361
+ />
1362
+ </ImageBackground>
1363
+ </ViewShot>
1364
+ ) : null
1365
+ ) : drawRegion ? (
1222
1366
  <ViewShot
1223
1367
  ref={viewShot}
1224
1368
  options={{
1225
1369
  format: 'jpg',
1226
1370
  quality: 1,
1227
- ...originalImageSize,
1371
+ ...drawRegion,
1228
1372
  }}
1229
- style={imageSize}
1373
+ style={drawRegion}
1230
1374
  >
1231
- <ImageBackground source={image} style={styles.bgImage}>
1232
- <DrawPad
1233
- currentItem={currentItem}
1234
- doneItems={doneItems}
1235
- onPressItem={onPressItem}
1236
- onTextHeightChange={onTextHeightChange}
1237
- />
1238
- </ImageBackground>
1375
+ <DrawPad
1376
+ currentItem={currentItem}
1377
+ doneItems={drawStates.doneItems}
1378
+ onPressItem={onPressItem}
1379
+ onTextHeightChange={onTextHeightChange}
1380
+ />
1239
1381
  </ViewShot>
1240
- ) : null
1241
- ) : drawRegion ? (
1242
- <ViewShot
1243
- ref={viewShot}
1244
- options={{
1245
- format: 'jpg',
1246
- quality: 1,
1247
- ...drawRegion,
1248
- }}
1249
- style={drawRegion}
1250
- >
1251
- <DrawPad
1252
- currentItem={currentItem}
1253
- doneItems={doneItems}
1254
- onPressItem={onPressItem}
1255
- onTextHeightChange={onTextHeightChange}
1256
- />
1257
- </ViewShot>
1258
- ) : null}
1382
+ ) : null}
1383
+ </View>
1384
+ </Animated.View>
1385
+ </PanGestureHandler>
1386
+
1387
+ <Animated.View style={[styles.rightPaneBaseStyle, rightPaneStyle]}>
1388
+ <View style={styles.strokeSliderContainer}>
1389
+ <StrokeSlider
1390
+ minValue={2}
1391
+ maxValue={10}
1392
+ stroke={strokeWidth}
1393
+ onStrokeChange={onColorStrokeChange}
1394
+ />
1395
+ </View>
1396
+ <View style={styles.colorSliderContainer}>
1397
+ <ColorSlider
1398
+ color={color}
1399
+ linearGradient={linearGradient}
1400
+ onColorChange={onColorStrokeChange}
1401
+ />
1259
1402
  </View>
1260
1403
  </Animated.View>
1261
- </PanGestureHandler>
1262
-
1263
- <Animated.View style={[styles.rightPaneBaseStyle, rightPaneStyle]}>
1264
- <View style={styles.strokeSliderContainer}>
1265
- <StrokeSlider minValue={2} maxValue={10} stroke={strokeWidth} />
1266
- </View>
1267
- <View style={styles.colorSliderContainer}>
1268
- <ColorSlider color={color} linearGradient={linearGradient} />
1269
- </View>
1270
- </Animated.View>
1404
+ </View>
1405
+ {Platform.OS === 'ios' ? (
1406
+ <InputAccessoryView>
1407
+ <AnimatedTextInput
1408
+ ref={textInputRef}
1409
+ style={[styles.textInput, textInputStyle]}
1410
+ onEndEditing={textInputRef.current?.clear}
1411
+ onChangeText={setTextVal}
1412
+ value={textVal}
1413
+ autoCorrect={false}
1414
+ />
1415
+ </InputAccessoryView>
1416
+ ) : (
1417
+ <Animated.View style={textInputContainerStyle}>
1418
+ <TextInput
1419
+ ref={textInputRef}
1420
+ style={styles.textInput}
1421
+ onEndEditing={textInputRef.current?.clear}
1422
+ onChangeText={setTextVal}
1423
+ value={textVal}
1424
+ autoCorrect={false}
1425
+ />
1426
+ </Animated.View>
1427
+ )}
1271
1428
  </View>
1272
- {Platform.OS === 'ios' ? (
1273
- <InputAccessoryView>
1274
- <AnimatedTextInput
1275
- ref={textInputRef}
1276
- style={[styles.textInput, textInputStyle]}
1277
- onEndEditing={textInputRef.current?.clear}
1278
- onChangeText={setTextVal}
1279
- value={textVal}
1280
- autoCorrect={false}
1281
- />
1282
- </InputAccessoryView>
1283
- ) : (
1284
- <Animated.View style={textInputContainerStyle}>
1285
- <TextInput
1286
- ref={textInputRef}
1287
- style={styles.textInput}
1288
- onEndEditing={textInputRef.current?.clear}
1289
- onChangeText={setTextVal}
1290
- value={textVal}
1291
- autoCorrect={false}
1292
- />
1293
- </Animated.View>
1294
- )}
1295
- </View>
1296
- );
1297
- });
1429
+ );
1430
+ }
1431
+ );
1298
1432
 
1299
1433
  export default DrawCore;