@archireport/react-native-drawing 0.2.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.
- package/README.md +181 -0
- package/lib/commonjs/DrawingEditor.js +815 -0
- package/lib/commonjs/DrawingEditor.js.map +1 -0
- package/lib/commonjs/assets/toolbar-icons/arrow-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/arrow-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/arrow.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/circle-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/circle-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/circle.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/freehand-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/freehand-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/freehand.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/line-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/line-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/line.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/measure-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/measure-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/measure.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/move-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/move-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/move.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/polygon-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/polygon-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/polygon.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/rectangle-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/rectangle-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/rectangle.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/text-disabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/text-enabled.png +0 -0
- package/lib/commonjs/assets/toolbar-icons/text.png +0 -0
- package/lib/commonjs/components/ColorPalette.js +379 -0
- package/lib/commonjs/components/ColorPalette.js.map +1 -0
- package/lib/commonjs/components/LineWidthSlider.js +70 -0
- package/lib/commonjs/components/LineWidthSlider.js.map +1 -0
- package/lib/commonjs/components/MeasurementEditModal.js +153 -0
- package/lib/commonjs/components/MeasurementEditModal.js.map +1 -0
- package/lib/commonjs/components/MiniMap.js +244 -0
- package/lib/commonjs/components/MiniMap.js.map +1 -0
- package/lib/commonjs/components/TextAnnotation.js +162 -0
- package/lib/commonjs/components/TextAnnotation.js.map +1 -0
- package/lib/commonjs/components/TextEditModal.js +133 -0
- package/lib/commonjs/components/TextEditModal.js.map +1 -0
- package/lib/commonjs/components/Toolbar.js +198 -0
- package/lib/commonjs/components/Toolbar.js.map +1 -0
- package/lib/commonjs/components/ZoomBadge.js +161 -0
- package/lib/commonjs/components/ZoomBadge.js.map +1 -0
- package/lib/commonjs/hooks/useFreehandGesture.js +173 -0
- package/lib/commonjs/hooks/useFreehandGesture.js.map +1 -0
- package/lib/commonjs/hooks/usePolygonGesture.js +109 -0
- package/lib/commonjs/hooks/usePolygonGesture.js.map +1 -0
- package/lib/commonjs/hooks/useSelectionGesture.js +236 -0
- package/lib/commonjs/hooks/useSelectionGesture.js.map +1 -0
- package/lib/commonjs/hooks/useShapeGesture.js +181 -0
- package/lib/commonjs/hooks/useShapeGesture.js.map +1 -0
- package/lib/commonjs/hooks/useViewportGesture.js +238 -0
- package/lib/commonjs/hooks/useViewportGesture.js.map +1 -0
- package/lib/commonjs/index.js +104 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/renderers/ArrowRenderer.js +118 -0
- package/lib/commonjs/renderers/ArrowRenderer.js.map +1 -0
- package/lib/commonjs/renderers/CircleRenderer.js +51 -0
- package/lib/commonjs/renderers/CircleRenderer.js.map +1 -0
- package/lib/commonjs/renderers/FreehandRenderer.js +31 -0
- package/lib/commonjs/renderers/FreehandRenderer.js.map +1 -0
- package/lib/commonjs/renderers/InProgressRenderer.js +174 -0
- package/lib/commonjs/renderers/InProgressRenderer.js.map +1 -0
- package/lib/commonjs/renderers/LineRenderer.js +27 -0
- package/lib/commonjs/renderers/LineRenderer.js.map +1 -0
- package/lib/commonjs/renderers/MeasurementRenderer.js +134 -0
- package/lib/commonjs/renderers/MeasurementRenderer.js.map +1 -0
- package/lib/commonjs/renderers/ObjectRenderer.js +65 -0
- package/lib/commonjs/renderers/ObjectRenderer.js.map +1 -0
- package/lib/commonjs/renderers/PolygonRenderer.js +46 -0
- package/lib/commonjs/renderers/PolygonRenderer.js.map +1 -0
- package/lib/commonjs/renderers/RectRenderer.js +51 -0
- package/lib/commonjs/renderers/RectRenderer.js.map +1 -0
- package/lib/commonjs/renderers/SelectedObjectRenderer.js +592 -0
- package/lib/commonjs/renderers/SelectedObjectRenderer.js.map +1 -0
- package/lib/commonjs/renderers/SelectionOverlay.js +120 -0
- package/lib/commonjs/renderers/SelectionOverlay.js.map +1 -0
- package/lib/commonjs/store/useDrawingStore.js +354 -0
- package/lib/commonjs/store/useDrawingStore.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/colors.js +44 -0
- package/lib/commonjs/utils/colors.js.map +1 -0
- package/lib/commonjs/utils/coordinates.js +81 -0
- package/lib/commonjs/utils/coordinates.js.map +1 -0
- package/lib/commonjs/utils/hitTesting.js +181 -0
- package/lib/commonjs/utils/hitTesting.js.map +1 -0
- package/lib/commonjs/utils/serialization.js +42 -0
- package/lib/commonjs/utils/serialization.js.map +1 -0
- package/lib/commonjs/utils/shapeDetection.js +151 -0
- package/lib/commonjs/utils/shapeDetection.js.map +1 -0
- package/lib/commonjs/utils/smoothing.js +85 -0
- package/lib/commonjs/utils/smoothing.js.map +1 -0
- package/lib/module/DrawingEditor.js +811 -0
- package/lib/module/DrawingEditor.js.map +1 -0
- package/lib/module/assets/toolbar-icons/arrow-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/arrow-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/arrow.png +0 -0
- package/lib/module/assets/toolbar-icons/circle-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/circle-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/circle.png +0 -0
- package/lib/module/assets/toolbar-icons/freehand-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/freehand-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/freehand.png +0 -0
- package/lib/module/assets/toolbar-icons/line-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/line-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/line.png +0 -0
- package/lib/module/assets/toolbar-icons/measure-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/measure-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/measure.png +0 -0
- package/lib/module/assets/toolbar-icons/move-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/move-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/move.png +0 -0
- package/lib/module/assets/toolbar-icons/polygon-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/polygon-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/polygon.png +0 -0
- package/lib/module/assets/toolbar-icons/rectangle-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/rectangle-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/rectangle.png +0 -0
- package/lib/module/assets/toolbar-icons/text-disabled.png +0 -0
- package/lib/module/assets/toolbar-icons/text-enabled.png +0 -0
- package/lib/module/assets/toolbar-icons/text.png +0 -0
- package/lib/module/components/ColorPalette.js +374 -0
- package/lib/module/components/ColorPalette.js.map +1 -0
- package/lib/module/components/LineWidthSlider.js +64 -0
- package/lib/module/components/LineWidthSlider.js.map +1 -0
- package/lib/module/components/MeasurementEditModal.js +148 -0
- package/lib/module/components/MeasurementEditModal.js.map +1 -0
- package/lib/module/components/MiniMap.js +239 -0
- package/lib/module/components/MiniMap.js.map +1 -0
- package/lib/module/components/TextAnnotation.js +157 -0
- package/lib/module/components/TextAnnotation.js.map +1 -0
- package/lib/module/components/TextEditModal.js +128 -0
- package/lib/module/components/TextEditModal.js.map +1 -0
- package/lib/module/components/Toolbar.js +193 -0
- package/lib/module/components/Toolbar.js.map +1 -0
- package/lib/module/components/ZoomBadge.js +155 -0
- package/lib/module/components/ZoomBadge.js.map +1 -0
- package/lib/module/hooks/useFreehandGesture.js +169 -0
- package/lib/module/hooks/useFreehandGesture.js.map +1 -0
- package/lib/module/hooks/usePolygonGesture.js +106 -0
- package/lib/module/hooks/usePolygonGesture.js.map +1 -0
- package/lib/module/hooks/useSelectionGesture.js +232 -0
- package/lib/module/hooks/useSelectionGesture.js.map +1 -0
- package/lib/module/hooks/useShapeGesture.js +177 -0
- package/lib/module/hooks/useShapeGesture.js.map +1 -0
- package/lib/module/hooks/useViewportGesture.js +234 -0
- package/lib/module/hooks/useViewportGesture.js.map +1 -0
- package/lib/module/index.js +20 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/renderers/ArrowRenderer.js +113 -0
- package/lib/module/renderers/ArrowRenderer.js.map +1 -0
- package/lib/module/renderers/CircleRenderer.js +46 -0
- package/lib/module/renderers/CircleRenderer.js.map +1 -0
- package/lib/module/renderers/FreehandRenderer.js +26 -0
- package/lib/module/renderers/FreehandRenderer.js.map +1 -0
- package/lib/module/renderers/InProgressRenderer.js +169 -0
- package/lib/module/renderers/InProgressRenderer.js.map +1 -0
- package/lib/module/renderers/LineRenderer.js +22 -0
- package/lib/module/renderers/LineRenderer.js.map +1 -0
- package/lib/module/renderers/MeasurementRenderer.js +129 -0
- package/lib/module/renderers/MeasurementRenderer.js.map +1 -0
- package/lib/module/renderers/ObjectRenderer.js +60 -0
- package/lib/module/renderers/ObjectRenderer.js.map +1 -0
- package/lib/module/renderers/PolygonRenderer.js +41 -0
- package/lib/module/renderers/PolygonRenderer.js.map +1 -0
- package/lib/module/renderers/RectRenderer.js +46 -0
- package/lib/module/renderers/RectRenderer.js.map +1 -0
- package/lib/module/renderers/SelectedObjectRenderer.js +587 -0
- package/lib/module/renderers/SelectedObjectRenderer.js.map +1 -0
- package/lib/module/renderers/SelectionOverlay.js +116 -0
- package/lib/module/renderers/SelectionOverlay.js.map +1 -0
- package/lib/module/store/useDrawingStore.js +350 -0
- package/lib/module/store/useDrawingStore.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/colors.js +40 -0
- package/lib/module/utils/colors.js.map +1 -0
- package/lib/module/utils/coordinates.js +71 -0
- package/lib/module/utils/coordinates.js.map +1 -0
- package/lib/module/utils/hitTesting.js +171 -0
- package/lib/module/utils/hitTesting.js.map +1 -0
- package/lib/module/utils/serialization.js +36 -0
- package/lib/module/utils/serialization.js.map +1 -0
- package/lib/module/utils/shapeDetection.js +147 -0
- package/lib/module/utils/shapeDetection.js.map +1 -0
- package/lib/module/utils/smoothing.js +80 -0
- package/lib/module/utils/smoothing.js.map +1 -0
- package/lib/typescript/DrawingEditor.d.ts +3 -0
- package/lib/typescript/DrawingEditor.d.ts.map +1 -0
- package/lib/typescript/components/ColorPalette.d.ts +9 -0
- package/lib/typescript/components/ColorPalette.d.ts.map +1 -0
- package/lib/typescript/components/LineWidthSlider.d.ts +11 -0
- package/lib/typescript/components/LineWidthSlider.d.ts.map +1 -0
- package/lib/typescript/components/MeasurementEditModal.d.ts +11 -0
- package/lib/typescript/components/MeasurementEditModal.d.ts.map +1 -0
- package/lib/typescript/components/MiniMap.d.ts +23 -0
- package/lib/typescript/components/MiniMap.d.ts.map +1 -0
- package/lib/typescript/components/TextAnnotation.d.ts +22 -0
- package/lib/typescript/components/TextAnnotation.d.ts.map +1 -0
- package/lib/typescript/components/TextEditModal.d.ts +10 -0
- package/lib/typescript/components/TextEditModal.d.ts.map +1 -0
- package/lib/typescript/components/Toolbar.d.ts +13 -0
- package/lib/typescript/components/Toolbar.d.ts.map +1 -0
- package/lib/typescript/components/ZoomBadge.d.ts +9 -0
- package/lib/typescript/components/ZoomBadge.d.ts.map +1 -0
- package/lib/typescript/hooks/useFreehandGesture.d.ts +47 -0
- package/lib/typescript/hooks/useFreehandGesture.d.ts.map +1 -0
- package/lib/typescript/hooks/usePolygonGesture.d.ts +47 -0
- package/lib/typescript/hooks/usePolygonGesture.d.ts.map +1 -0
- package/lib/typescript/hooks/useSelectionGesture.d.ts +32 -0
- package/lib/typescript/hooks/useSelectionGesture.d.ts.map +1 -0
- package/lib/typescript/hooks/useShapeGesture.d.ts +54 -0
- package/lib/typescript/hooks/useShapeGesture.d.ts.map +1 -0
- package/lib/typescript/hooks/useViewportGesture.d.ts +37 -0
- package/lib/typescript/hooks/useViewportGesture.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +11 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/renderers/ArrowRenderer.d.ts +9 -0
- package/lib/typescript/renderers/ArrowRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/CircleRenderer.d.ts +9 -0
- package/lib/typescript/renderers/CircleRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/FreehandRenderer.d.ts +9 -0
- package/lib/typescript/renderers/FreehandRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/InProgressRenderer.d.ts +32 -0
- package/lib/typescript/renderers/InProgressRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/LineRenderer.d.ts +9 -0
- package/lib/typescript/renderers/LineRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/MeasurementRenderer.d.ts +9 -0
- package/lib/typescript/renderers/MeasurementRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/ObjectRenderer.d.ts +12 -0
- package/lib/typescript/renderers/ObjectRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/PolygonRenderer.d.ts +13 -0
- package/lib/typescript/renderers/PolygonRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/RectRenderer.d.ts +9 -0
- package/lib/typescript/renderers/RectRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/SelectedObjectRenderer.d.ts +18 -0
- package/lib/typescript/renderers/SelectedObjectRenderer.d.ts.map +1 -0
- package/lib/typescript/renderers/SelectionOverlay.d.ts +21 -0
- package/lib/typescript/renderers/SelectionOverlay.d.ts.map +1 -0
- package/lib/typescript/store/useDrawingStore.d.ts +30 -0
- package/lib/typescript/store/useDrawingStore.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +130 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils/colors.d.ts +11 -0
- package/lib/typescript/utils/colors.d.ts.map +1 -0
- package/lib/typescript/utils/coordinates.d.ts +34 -0
- package/lib/typescript/utils/coordinates.d.ts.map +1 -0
- package/lib/typescript/utils/hitTesting.d.ts +18 -0
- package/lib/typescript/utils/hitTesting.d.ts.map +1 -0
- package/lib/typescript/utils/serialization.d.ts +17 -0
- package/lib/typescript/utils/serialization.d.ts.map +1 -0
- package/lib/typescript/utils/shapeDetection.d.ts +22 -0
- package/lib/typescript/utils/shapeDetection.d.ts.map +1 -0
- package/lib/typescript/utils/smoothing.d.ts +16 -0
- package/lib/typescript/utils/smoothing.d.ts.map +1 -0
- package/package.json +108 -0
- package/src/DrawingEditor.tsx +1071 -0
- package/src/assets/toolbar-icons/arrow-disabled.png +0 -0
- package/src/assets/toolbar-icons/arrow-enabled.png +0 -0
- package/src/assets/toolbar-icons/arrow.png +0 -0
- package/src/assets/toolbar-icons/circle-disabled.png +0 -0
- package/src/assets/toolbar-icons/circle-enabled.png +0 -0
- package/src/assets/toolbar-icons/circle.png +0 -0
- package/src/assets/toolbar-icons/freehand-disabled.png +0 -0
- package/src/assets/toolbar-icons/freehand-enabled.png +0 -0
- package/src/assets/toolbar-icons/freehand.png +0 -0
- package/src/assets/toolbar-icons/line-disabled.png +0 -0
- package/src/assets/toolbar-icons/line-enabled.png +0 -0
- package/src/assets/toolbar-icons/line.png +0 -0
- package/src/assets/toolbar-icons/measure-disabled.png +0 -0
- package/src/assets/toolbar-icons/measure-enabled.png +0 -0
- package/src/assets/toolbar-icons/measure.png +0 -0
- package/src/assets/toolbar-icons/move-disabled.png +0 -0
- package/src/assets/toolbar-icons/move-enabled.png +0 -0
- package/src/assets/toolbar-icons/move.png +0 -0
- package/src/assets/toolbar-icons/polygon-disabled.png +0 -0
- package/src/assets/toolbar-icons/polygon-enabled.png +0 -0
- package/src/assets/toolbar-icons/polygon.png +0 -0
- package/src/assets/toolbar-icons/rectangle-disabled.png +0 -0
- package/src/assets/toolbar-icons/rectangle-enabled.png +0 -0
- package/src/assets/toolbar-icons/rectangle.png +0 -0
- package/src/assets/toolbar-icons/text-disabled.png +0 -0
- package/src/assets/toolbar-icons/text-enabled.png +0 -0
- package/src/assets/toolbar-icons/text.png +0 -0
- package/src/components/ColorPalette.tsx +497 -0
- package/src/components/LineWidthSlider.tsx +87 -0
- package/src/components/MeasurementEditModal.tsx +163 -0
- package/src/components/MiniMap.tsx +275 -0
- package/src/components/TextAnnotation.tsx +198 -0
- package/src/components/TextEditModal.tsx +139 -0
- package/src/components/Toolbar.tsx +254 -0
- package/src/components/ZoomBadge.tsx +166 -0
- package/src/hooks/useFreehandGesture.ts +249 -0
- package/src/hooks/usePolygonGesture.ts +162 -0
- package/src/hooks/useSelectionGesture.ts +293 -0
- package/src/hooks/useShapeGesture.ts +256 -0
- package/src/hooks/useViewportGesture.ts +337 -0
- package/src/index.tsx +51 -0
- package/src/renderers/ArrowRenderer.tsx +123 -0
- package/src/renderers/CircleRenderer.tsx +60 -0
- package/src/renderers/FreehandRenderer.tsx +33 -0
- package/src/renderers/InProgressRenderer.tsx +217 -0
- package/src/renderers/LineRenderer.tsx +34 -0
- package/src/renderers/MeasurementRenderer.tsx +179 -0
- package/src/renderers/ObjectRenderer.tsx +42 -0
- package/src/renderers/PolygonRenderer.tsx +66 -0
- package/src/renderers/RectRenderer.tsx +60 -0
- package/src/renderers/SelectedObjectRenderer.tsx +738 -0
- package/src/renderers/SelectionOverlay.tsx +170 -0
- package/src/store/useDrawingStore.ts +357 -0
- package/src/types.ts +186 -0
- package/src/utils/colors.ts +98 -0
- package/src/utils/coordinates.ts +75 -0
- package/src/utils/hitTesting.ts +242 -0
- package/src/utils/serialization.ts +45 -0
- package/src/utils/shapeDetection.ts +160 -0
- package/src/utils/smoothing.ts +84 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
import { Gesture } from "react-native-gesture-handler";
|
|
5
|
+
import { useSharedValue, withTiming, runOnJS } from "react-native-reanimated";
|
|
6
|
+
const DEFAULT_MAX_ZOOM = 5;
|
|
7
|
+
const RESET_DURATION = 250;
|
|
8
|
+
function clampTranslate(tx, ty, scale, _layoutW, _layoutH, imgOffX, imgOffY, imgW, imgH) {
|
|
9
|
+
"worklet";
|
|
10
|
+
|
|
11
|
+
// The image occupies [imgOffX, imgOffY] to [imgOffX+imgW, imgOffY+imgH] in layout space.
|
|
12
|
+
// After zoom, the image spans imgW*scale in canvas coords, displayed from (imgOffX*scale + tx).
|
|
13
|
+
// We want the scaled image to cover its original area:
|
|
14
|
+
// - Left edge of scaled image <= left edge of original area: imgOffX*scale + tx <= imgOffX
|
|
15
|
+
// - Right edge of scaled image >= right edge of original area: imgOffX*scale + tx + imgW*scale >= imgOffX + imgW
|
|
16
|
+
// Simplify:
|
|
17
|
+
// tx <= imgOffX * (1 - scale)
|
|
18
|
+
// tx >= (imgOffX + imgW) * (1 - scale) + (layoutW - imgOffX - imgW) ... no, let's think differently.
|
|
19
|
+
//
|
|
20
|
+
// Viewport model: the canvas is rendered with transform [translate(tx,ty), scale(s)] applied from origin.
|
|
21
|
+
// A point at canvas coords (cx, cy) maps to screen (cx*s + tx, cy*s + ty).
|
|
22
|
+
// Image starts at canvas (imgOffX, imgOffY) with size (imgW, imgH).
|
|
23
|
+
// On screen, image top-left = (imgOffX*s + tx, imgOffY*s + ty).
|
|
24
|
+
// On screen, image bottom-right = ((imgOffX+imgW)*s + tx, (imgOffY+imgH)*s + ty).
|
|
25
|
+
//
|
|
26
|
+
// Constraint: image should fill the original viewport area [imgOffX..imgOffX+imgW] x [imgOffY..imgOffY+imgH]:
|
|
27
|
+
// imgOffX*s + tx <= imgOffX => tx <= imgOffX*(1-s)
|
|
28
|
+
// (imgOffX+imgW)*s + tx >= imgOffX+imgW => tx >= (imgOffX+imgW)*(1-s)
|
|
29
|
+
// same for Y.
|
|
30
|
+
const minTx = (imgOffX + imgW) * (1 - scale);
|
|
31
|
+
const maxTx = imgOffX * (1 - scale);
|
|
32
|
+
const minTy = (imgOffY + imgH) * (1 - scale);
|
|
33
|
+
const maxTy = imgOffY * (1 - scale);
|
|
34
|
+
const clampedTx = Math.min(maxTx, Math.max(minTx, tx));
|
|
35
|
+
const clampedTy = Math.min(maxTy, Math.max(minTy, ty));
|
|
36
|
+
return [clampedTx, clampedTy];
|
|
37
|
+
}
|
|
38
|
+
export function useViewportGesture({
|
|
39
|
+
maxZoom = DEFAULT_MAX_ZOOM,
|
|
40
|
+
layoutWidth,
|
|
41
|
+
layoutHeight,
|
|
42
|
+
imageOffsetX,
|
|
43
|
+
imageOffsetY,
|
|
44
|
+
imageWidth,
|
|
45
|
+
imageHeight,
|
|
46
|
+
onPinchEnd
|
|
47
|
+
}) {
|
|
48
|
+
const scale = useSharedValue(1);
|
|
49
|
+
const translateX = useSharedValue(0);
|
|
50
|
+
const translateY = useSharedValue(0);
|
|
51
|
+
|
|
52
|
+
// Saved state at gesture start
|
|
53
|
+
const savedScale = useSharedValue(1);
|
|
54
|
+
const savedTranslateX = useSharedValue(0);
|
|
55
|
+
const savedTranslateY = useSharedValue(0);
|
|
56
|
+
|
|
57
|
+
// Saved focal point at pinch start (for stable zoom center)
|
|
58
|
+
const savedFocalX = useSharedValue(0);
|
|
59
|
+
const savedFocalY = useSharedValue(0);
|
|
60
|
+
|
|
61
|
+
// Flag to prevent 2-finger pan from interfering during pinch
|
|
62
|
+
const isPinching = useSharedValue(false);
|
|
63
|
+
|
|
64
|
+
// ─── Pinch-to-zoom ──────────────────────────────────────────────────────
|
|
65
|
+
const pinchGesture = Gesture.Pinch().onBegin(e => {
|
|
66
|
+
"worklet";
|
|
67
|
+
|
|
68
|
+
isPinching.value = true;
|
|
69
|
+
savedScale.value = scale.value;
|
|
70
|
+
savedTranslateX.value = translateX.value;
|
|
71
|
+
savedTranslateY.value = translateY.value;
|
|
72
|
+
savedFocalX.value = e.focalX;
|
|
73
|
+
savedFocalY.value = e.focalY;
|
|
74
|
+
}).onUpdate(e => {
|
|
75
|
+
"worklet";
|
|
76
|
+
|
|
77
|
+
const newScale = Math.min(maxZoom, Math.max(1, savedScale.value * e.scale));
|
|
78
|
+
|
|
79
|
+
// Canvas point under initial focal at gesture start:
|
|
80
|
+
const canvasFocalX = (savedFocalX.value - savedTranslateX.value) / savedScale.value;
|
|
81
|
+
const canvasFocalY = (savedFocalY.value - savedTranslateY.value) / savedScale.value;
|
|
82
|
+
|
|
83
|
+
// Pan delta from finger movement since gesture start:
|
|
84
|
+
const focalDeltaX = e.focalX - savedFocalX.value;
|
|
85
|
+
const focalDeltaY = e.focalY - savedFocalY.value;
|
|
86
|
+
|
|
87
|
+
// New translate: zoom around initial focal + follow finger pan
|
|
88
|
+
const newTx = savedFocalX.value - canvasFocalX * newScale + focalDeltaX;
|
|
89
|
+
const newTy = savedFocalY.value - canvasFocalY * newScale + focalDeltaY;
|
|
90
|
+
scale.value = newScale;
|
|
91
|
+
const [cx, cy] = clampTranslate(newTx, newTy, newScale, layoutWidth.value, layoutHeight.value, imageOffsetX.value, imageOffsetY.value, imageWidth.value, imageHeight.value);
|
|
92
|
+
translateX.value = cx;
|
|
93
|
+
translateY.value = cy;
|
|
94
|
+
}).onEnd(() => {
|
|
95
|
+
"worklet";
|
|
96
|
+
|
|
97
|
+
isPinching.value = false;
|
|
98
|
+
if (scale.value <= 1.05) {
|
|
99
|
+
// Snap back to 1x if close enough
|
|
100
|
+
scale.value = withTiming(1, {
|
|
101
|
+
duration: RESET_DURATION
|
|
102
|
+
});
|
|
103
|
+
translateX.value = withTiming(0, {
|
|
104
|
+
duration: RESET_DURATION
|
|
105
|
+
});
|
|
106
|
+
translateY.value = withTiming(0, {
|
|
107
|
+
duration: RESET_DURATION
|
|
108
|
+
});
|
|
109
|
+
} else if (onPinchEnd) {
|
|
110
|
+
// Zoomed in — notify caller so it can deactivate the tool
|
|
111
|
+
runOnJS(onPinchEnd)();
|
|
112
|
+
}
|
|
113
|
+
}).onFinalize(() => {
|
|
114
|
+
"worklet";
|
|
115
|
+
|
|
116
|
+
isPinching.value = false;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// ─── Two-finger pan (only when zoomed and NOT pinching) ─────────────────
|
|
120
|
+
const twoFingerPanGesture = Gesture.Pan().minPointers(2).maxPointers(2).onBegin(() => {
|
|
121
|
+
"worklet";
|
|
122
|
+
|
|
123
|
+
savedTranslateX.value = translateX.value;
|
|
124
|
+
savedTranslateY.value = translateY.value;
|
|
125
|
+
}).onUpdate(e => {
|
|
126
|
+
"worklet";
|
|
127
|
+
|
|
128
|
+
// Skip if pinch is active — pinch handles its own panning
|
|
129
|
+
if (isPinching.value) return;
|
|
130
|
+
if (scale.value <= 1) return;
|
|
131
|
+
const newTx = savedTranslateX.value + e.translationX;
|
|
132
|
+
const newTy = savedTranslateY.value + e.translationY;
|
|
133
|
+
const [cx, cy] = clampTranslate(newTx, newTy, scale.value, layoutWidth.value, layoutHeight.value, imageOffsetX.value, imageOffsetY.value, imageWidth.value, imageHeight.value);
|
|
134
|
+
translateX.value = cx;
|
|
135
|
+
translateY.value = cy;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// ─── Single-finger pan (when zoomed with no active tool) ───────────────
|
|
139
|
+
const singleFingerPanGesture = Gesture.Pan().minPointers(1).maxPointers(1).minDistance(5).onBegin(() => {
|
|
140
|
+
"worklet";
|
|
141
|
+
|
|
142
|
+
savedTranslateX.value = translateX.value;
|
|
143
|
+
savedTranslateY.value = translateY.value;
|
|
144
|
+
}).onUpdate(e => {
|
|
145
|
+
"worklet";
|
|
146
|
+
|
|
147
|
+
if (scale.value <= 1) return;
|
|
148
|
+
const newTx = savedTranslateX.value + e.translationX;
|
|
149
|
+
const newTy = savedTranslateY.value + e.translationY;
|
|
150
|
+
const [cx, cy] = clampTranslate(newTx, newTy, scale.value, layoutWidth.value, layoutHeight.value, imageOffsetX.value, imageOffsetY.value, imageWidth.value, imageHeight.value);
|
|
151
|
+
translateX.value = cx;
|
|
152
|
+
translateY.value = cy;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// ─── Double-tap two-finger reset ───────────────────────────────────────
|
|
156
|
+
const doubleTapResetGesture = Gesture.Tap().numberOfTaps(2).minPointers(2).maxDuration(500).onEnd(() => {
|
|
157
|
+
"worklet";
|
|
158
|
+
|
|
159
|
+
scale.value = withTiming(1, {
|
|
160
|
+
duration: RESET_DURATION
|
|
161
|
+
});
|
|
162
|
+
translateX.value = withTiming(0, {
|
|
163
|
+
duration: RESET_DURATION
|
|
164
|
+
});
|
|
165
|
+
translateY.value = withTiming(0, {
|
|
166
|
+
duration: RESET_DURATION
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// ─── Programmatic reset ────────────────────────────────────────────────
|
|
171
|
+
const resetViewport = useCallback(() => {
|
|
172
|
+
scale.value = withTiming(1, {
|
|
173
|
+
duration: RESET_DURATION
|
|
174
|
+
});
|
|
175
|
+
translateX.value = withTiming(0, {
|
|
176
|
+
duration: RESET_DURATION
|
|
177
|
+
});
|
|
178
|
+
translateY.value = withTiming(0, {
|
|
179
|
+
duration: RESET_DURATION
|
|
180
|
+
});
|
|
181
|
+
}, [scale, translateX, translateY]);
|
|
182
|
+
const zoomAt = useCallback((screenX, screenY, scaleFactor) => {
|
|
183
|
+
if (imageWidth.value <= 0 || imageHeight.value <= 0) return;
|
|
184
|
+
const previousScale = scale.value;
|
|
185
|
+
const nextScale = Math.min(maxZoom, Math.max(1, previousScale * scaleFactor));
|
|
186
|
+
if (Math.abs(nextScale - previousScale) < 0.001) return;
|
|
187
|
+
if (nextScale <= 1.05) {
|
|
188
|
+
scale.value = withTiming(1, {
|
|
189
|
+
duration: RESET_DURATION
|
|
190
|
+
});
|
|
191
|
+
translateX.value = withTiming(0, {
|
|
192
|
+
duration: RESET_DURATION
|
|
193
|
+
});
|
|
194
|
+
translateY.value = withTiming(0, {
|
|
195
|
+
duration: RESET_DURATION
|
|
196
|
+
});
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const canvasFocalX = (screenX - translateX.value) / previousScale;
|
|
200
|
+
const canvasFocalY = (screenY - translateY.value) / previousScale;
|
|
201
|
+
const nextTranslateX = screenX - canvasFocalX * nextScale;
|
|
202
|
+
const nextTranslateY = screenY - canvasFocalY * nextScale;
|
|
203
|
+
const [clampedX, clampedY] = clampTranslate(nextTranslateX, nextTranslateY, nextScale, layoutWidth.value, layoutHeight.value, imageOffsetX.value, imageOffsetY.value, imageWidth.value, imageHeight.value);
|
|
204
|
+
scale.value = nextScale;
|
|
205
|
+
translateX.value = clampedX;
|
|
206
|
+
translateY.value = clampedY;
|
|
207
|
+
if (previousScale <= 1.05 && onPinchEnd) {
|
|
208
|
+
onPinchEnd();
|
|
209
|
+
}
|
|
210
|
+
}, [maxZoom, onPinchEnd, scale, translateX, translateY, layoutWidth, layoutHeight, imageOffsetX, imageOffsetY, imageWidth, imageHeight]);
|
|
211
|
+
|
|
212
|
+
// ─── Programmatic pan (for minimap drag) ────────────────────────────────
|
|
213
|
+
const panViewport = useCallback((dtx, dty) => {
|
|
214
|
+
const newTx = translateX.value + dtx;
|
|
215
|
+
const newTy = translateY.value + dty;
|
|
216
|
+
const [cx, cy] = clampTranslate(newTx, newTy, scale.value, layoutWidth.value, layoutHeight.value, imageOffsetX.value, imageOffsetY.value, imageWidth.value, imageHeight.value);
|
|
217
|
+
translateX.value = cx;
|
|
218
|
+
translateY.value = cy;
|
|
219
|
+
}, [scale, translateX, translateY, layoutWidth, layoutHeight, imageOffsetX, imageOffsetY, imageWidth, imageHeight]);
|
|
220
|
+
return {
|
|
221
|
+
pinchGesture,
|
|
222
|
+
twoFingerPanGesture,
|
|
223
|
+
singleFingerPanGesture,
|
|
224
|
+
doubleTapResetGesture,
|
|
225
|
+
scale,
|
|
226
|
+
translateX,
|
|
227
|
+
translateY,
|
|
228
|
+
isPinching,
|
|
229
|
+
resetViewport,
|
|
230
|
+
panViewport,
|
|
231
|
+
zoomAt
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=useViewportGesture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","Gesture","useSharedValue","withTiming","runOnJS","DEFAULT_MAX_ZOOM","RESET_DURATION","clampTranslate","tx","ty","scale","_layoutW","_layoutH","imgOffX","imgOffY","imgW","imgH","minTx","maxTx","minTy","maxTy","clampedTx","Math","min","max","clampedTy","useViewportGesture","maxZoom","layoutWidth","layoutHeight","imageOffsetX","imageOffsetY","imageWidth","imageHeight","onPinchEnd","translateX","translateY","savedScale","savedTranslateX","savedTranslateY","savedFocalX","savedFocalY","isPinching","pinchGesture","Pinch","onBegin","e","value","focalX","focalY","onUpdate","newScale","canvasFocalX","canvasFocalY","focalDeltaX","focalDeltaY","newTx","newTy","cx","cy","onEnd","duration","onFinalize","twoFingerPanGesture","Pan","minPointers","maxPointers","translationX","translationY","singleFingerPanGesture","minDistance","doubleTapResetGesture","Tap","numberOfTaps","maxDuration","resetViewport","zoomAt","screenX","screenY","scaleFactor","previousScale","nextScale","abs","nextTranslateX","nextTranslateY","clampedX","clampedY","panViewport","dtx","dty"],"sourceRoot":"../../../src","sources":["hooks/useViewportGesture.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// ─── Main Component ──────────────────────────────────────────────────────────
|
|
4
|
+
export { DrawingEditor } from "./DrawingEditor";
|
|
5
|
+
|
|
6
|
+
// ─── Store ───────────────────────────────────────────────────────────────────
|
|
7
|
+
export { useDrawingStore } from "./store/useDrawingStore";
|
|
8
|
+
|
|
9
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
// ─── Utilities ───────────────────────────────────────────────────────────────
|
|
12
|
+
export { normalize, denormalize, normalizePoints, denormalizePoints, screenToCanvas } from "./utils/coordinates";
|
|
13
|
+
export { serializeObjects, deserializeObjects, generateId } from "./utils/serialization";
|
|
14
|
+
export { PRESET_COLORS, DEFAULT_STROKE_COLOR } from "./utils/colors";
|
|
15
|
+
|
|
16
|
+
// ─── Reusable UI Components ─────────────────────────────────────────────────
|
|
17
|
+
export { Toolbar } from "./components/Toolbar";
|
|
18
|
+
export { ColorPalette } from "./components/ColorPalette";
|
|
19
|
+
export { LineWidthSlider } from "./components/LineWidthSlider";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DrawingEditor","useDrawingStore","normalize","denormalize","normalizePoints","denormalizePoints","screenToCanvas","serializeObjects","deserializeObjects","generateId","PRESET_COLORS","DEFAULT_STROKE_COLOR","Toolbar","ColorPalette","LineWidthSlider"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA,SAASA,aAAa,QAAQ,iBAAiB;;AAE/C;AACA,SAASC,eAAe,QAAQ,yBAAyB;;AAGzD;;AAyBA;AACA,SACEC,SAAS,EACTC,WAAW,EACXC,eAAe,EACfC,iBAAiB,EACjBC,cAAc,QACT,qBAAqB;AAC5B,SACEC,gBAAgB,EAChBC,kBAAkB,EAClBC,UAAU,QACL,uBAAuB;AAC9B,SAASC,aAAa,EAAEC,oBAAoB,QAAQ,gBAAgB;;AAEpE;AACA,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,eAAe,QAAQ,8BAA8B","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
|
+
import { Path } from "@shopify/react-native-skia";
|
|
5
|
+
import { denormalize } from "../utils/coordinates";
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
/**
|
|
8
|
+
* Build an arrow path.
|
|
9
|
+
* - lineWidth < 8: simple line + triangular head
|
|
10
|
+
* - lineWidth >= 8: filled body with wider triangular head
|
|
11
|
+
*/
|
|
12
|
+
function buildArrowPath(fx, fy, tx, ty, lineWidth) {
|
|
13
|
+
const dx = tx - fx;
|
|
14
|
+
const dy = ty - fy;
|
|
15
|
+
const len = Math.sqrt(dx * dx + dy * dy);
|
|
16
|
+
if (len === 0) return "";
|
|
17
|
+
const angle = Math.atan2(dy, dx);
|
|
18
|
+
const cos = Math.cos(angle);
|
|
19
|
+
const sin = Math.sin(angle);
|
|
20
|
+
if (lineWidth < 8) {
|
|
21
|
+
// Simple arrow: line + triangular head
|
|
22
|
+
const headLen = lineWidth * 2;
|
|
23
|
+
const headW = lineWidth * 2;
|
|
24
|
+
|
|
25
|
+
// Head points
|
|
26
|
+
const hx1 = tx - headLen * cos + headW / 2 * sin;
|
|
27
|
+
const hy1 = ty - headLen * sin - headW / 2 * cos;
|
|
28
|
+
const hx2 = tx - headLen * cos - headW / 2 * sin;
|
|
29
|
+
const hy2 = ty - headLen * sin + headW / 2 * cos;
|
|
30
|
+
return `M ${fx} ${fy} L ${tx} ${ty} ` + `M ${tx} ${ty} L ${hx1} ${hy1} M ${tx} ${ty} L ${hx2} ${hy2}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Filled arrow: rectangular body + triangular head
|
|
34
|
+
const headLen = lineWidth * 3;
|
|
35
|
+
const headW = lineWidth * 3;
|
|
36
|
+
const bodyW = lineWidth;
|
|
37
|
+
const bodyLen = Math.max(0, len - headLen);
|
|
38
|
+
|
|
39
|
+
// Body rectangle (in local space: from origin going right)
|
|
40
|
+
// Then transformed via rotation
|
|
41
|
+
const halfBody = bodyW / 2;
|
|
42
|
+
|
|
43
|
+
// Points in local space (arrow points to the right)
|
|
44
|
+
const b1 = {
|
|
45
|
+
x: 0,
|
|
46
|
+
y: -halfBody
|
|
47
|
+
};
|
|
48
|
+
const b2 = {
|
|
49
|
+
x: bodyLen,
|
|
50
|
+
y: -halfBody
|
|
51
|
+
};
|
|
52
|
+
const b3 = {
|
|
53
|
+
x: bodyLen,
|
|
54
|
+
y: halfBody
|
|
55
|
+
};
|
|
56
|
+
const b4 = {
|
|
57
|
+
x: 0,
|
|
58
|
+
y: halfBody
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Head triangle in local space
|
|
62
|
+
const h1 = {
|
|
63
|
+
x: bodyLen,
|
|
64
|
+
y: -headW / 2
|
|
65
|
+
};
|
|
66
|
+
const h2 = {
|
|
67
|
+
x: len,
|
|
68
|
+
y: 0
|
|
69
|
+
};
|
|
70
|
+
const h3 = {
|
|
71
|
+
x: bodyLen,
|
|
72
|
+
y: headW / 2
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Transform function: rotate + translate
|
|
76
|
+
const transform = p => ({
|
|
77
|
+
x: fx + p.x * cos - p.y * sin,
|
|
78
|
+
y: fy + p.x * sin + p.y * cos
|
|
79
|
+
});
|
|
80
|
+
const tb1 = transform(b1);
|
|
81
|
+
const tb2 = transform(b2);
|
|
82
|
+
const tb3 = transform(b3);
|
|
83
|
+
const tb4 = transform(b4);
|
|
84
|
+
const th1 = transform(h1);
|
|
85
|
+
const th2 = transform(h2);
|
|
86
|
+
const th3 = transform(h3);
|
|
87
|
+
return `M ${tb1.x} ${tb1.y} L ${tb2.x} ${tb2.y} L ${tb3.x} ${tb3.y} L ${tb4.x} ${tb4.y} Z ` + `M ${th1.x} ${th1.y} L ${th2.x} ${th2.y} L ${th3.x} ${th3.y} Z`;
|
|
88
|
+
}
|
|
89
|
+
export const ArrowRenderer = /*#__PURE__*/React.memo(function ArrowRenderer({
|
|
90
|
+
object,
|
|
91
|
+
canvasSize
|
|
92
|
+
}) {
|
|
93
|
+
const from = useMemo(() => denormalize(object.from, canvasSize), [object.from, canvasSize]);
|
|
94
|
+
const to = useMemo(() => denormalize(object.to, canvasSize), [object.to, canvasSize]);
|
|
95
|
+
const pathString = useMemo(() => buildArrowPath(from.x, from.y, to.x, to.y, object.lineWidth), [from, to, object.lineWidth]);
|
|
96
|
+
if (!pathString) return null;
|
|
97
|
+
if (object.lineWidth < 8) {
|
|
98
|
+
return /*#__PURE__*/_jsx(Path, {
|
|
99
|
+
path: pathString,
|
|
100
|
+
style: "stroke",
|
|
101
|
+
strokeWidth: object.lineWidth,
|
|
102
|
+
color: object.color,
|
|
103
|
+
strokeCap: "round",
|
|
104
|
+
strokeJoin: "round"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return /*#__PURE__*/_jsx(Path, {
|
|
108
|
+
path: pathString,
|
|
109
|
+
style: "fill",
|
|
110
|
+
color: object.color
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=ArrowRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useMemo","Path","denormalize","jsx","_jsx","buildArrowPath","fx","fy","tx","ty","lineWidth","dx","dy","len","Math","sqrt","angle","atan2","cos","sin","headLen","headW","hx1","hy1","hx2","hy2","bodyW","bodyLen","max","halfBody","b1","x","y","b2","b3","b4","h1","h2","h3","transform","p","tb1","tb2","tb3","tb4","th1","th2","th3","ArrowRenderer","memo","object","canvasSize","from","to","pathString","path","style","strokeWidth","color","strokeCap","strokeJoin"],"sourceRoot":"../../../src","sources":["renderers/ArrowRenderer.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
|
+
import { Oval, Group } from "@shopify/react-native-skia";
|
|
5
|
+
import { denormalize } from "../utils/coordinates";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
export const CircleRenderer = /*#__PURE__*/React.memo(function CircleRenderer({
|
|
8
|
+
object,
|
|
9
|
+
canvasSize
|
|
10
|
+
}) {
|
|
11
|
+
const from = useMemo(() => denormalize(object.from, canvasSize), [object.from, canvasSize]);
|
|
12
|
+
const to = useMemo(() => denormalize(object.to, canvasSize), [object.to, canvasSize]);
|
|
13
|
+
const rect = useMemo(() => {
|
|
14
|
+
const x = Math.min(from.x, to.x);
|
|
15
|
+
const y = Math.min(from.y, to.y);
|
|
16
|
+
const width = Math.abs(to.x - from.x);
|
|
17
|
+
const height = Math.abs(to.y - from.y);
|
|
18
|
+
return {
|
|
19
|
+
x,
|
|
20
|
+
y,
|
|
21
|
+
width,
|
|
22
|
+
height
|
|
23
|
+
};
|
|
24
|
+
}, [from, to]);
|
|
25
|
+
const hasFill = object.backgroundColor && object.backgroundAlpha;
|
|
26
|
+
const fillColor = hasFill ? object.backgroundColor.replace(/[\d.]+\)$/, `${object.backgroundAlpha})`) : undefined;
|
|
27
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
28
|
+
children: [fillColor && /*#__PURE__*/_jsx(Oval, {
|
|
29
|
+
x: rect.x,
|
|
30
|
+
y: rect.y,
|
|
31
|
+
width: rect.width,
|
|
32
|
+
height: rect.height,
|
|
33
|
+
color: fillColor,
|
|
34
|
+
style: "fill"
|
|
35
|
+
}), /*#__PURE__*/_jsx(Oval, {
|
|
36
|
+
x: rect.x,
|
|
37
|
+
y: rect.y,
|
|
38
|
+
width: rect.width,
|
|
39
|
+
height: rect.height,
|
|
40
|
+
color: object.color,
|
|
41
|
+
style: "stroke",
|
|
42
|
+
strokeWidth: object.lineWidth
|
|
43
|
+
})]
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=CircleRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useMemo","Oval","Group","denormalize","jsx","_jsx","jsxs","_jsxs","CircleRenderer","memo","object","canvasSize","from","to","rect","x","Math","min","y","width","abs","height","hasFill","backgroundColor","backgroundAlpha","fillColor","replace","undefined","children","color","style","strokeWidth","lineWidth"],"sourceRoot":"../../../src","sources":["renderers/CircleRenderer.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,IAAI,EAAEC,KAAK,QAAQ,4BAA4B;AAExD,SAASC,WAAW,QAAQ,sBAAsB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAOnD,OAAO,MAAMC,cAAc,gBAAGT,KAAK,CAACU,IAAI,CAAC,SAASD,cAAcA,CAAC;EAC/DE,MAAM;EACNC;AACmB,CAAC,EAAE;EACtB,MAAMC,IAAI,GAAGZ,OAAO,CAClB,MAAMG,WAAW,CAACO,MAAM,CAACE,IAAI,EAAED,UAAU,CAAC,EAC1C,CAACD,MAAM,CAACE,IAAI,EAAED,UAAU,CAC1B,CAAC;EACD,MAAME,EAAE,GAAGb,OAAO,CAChB,MAAMG,WAAW,CAACO,MAAM,CAACG,EAAE,EAAEF,UAAU,CAAC,EACxC,CAACD,MAAM,CAACG,EAAE,EAAEF,UAAU,CACxB,CAAC;EAED,MAAMG,IAAI,GAAGd,OAAO,CAAC,MAAM;IACzB,MAAMe,CAAC,GAAGC,IAAI,CAACC,GAAG,CAACL,IAAI,CAACG,CAAC,EAAEF,EAAE,CAACE,CAAC,CAAC;IAChC,MAAMG,CAAC,GAAGF,IAAI,CAACC,GAAG,CAACL,IAAI,CAACM,CAAC,EAAEL,EAAE,CAACK,CAAC,CAAC;IAChC,MAAMC,KAAK,GAAGH,IAAI,CAACI,GAAG,CAACP,EAAE,CAACE,CAAC,GAAGH,IAAI,CAACG,CAAC,CAAC;IACrC,MAAMM,MAAM,GAAGL,IAAI,CAACI,GAAG,CAACP,EAAE,CAACK,CAAC,GAAGN,IAAI,CAACM,CAAC,CAAC;IACtC,OAAO;MAAEH,CAAC;MAAEG,CAAC;MAAEC,KAAK;MAAEE;IAAO,CAAC;EAChC,CAAC,EAAE,CAACT,IAAI,EAAEC,EAAE,CAAC,CAAC;EAEd,MAAMS,OAAO,GAAGZ,MAAM,CAACa,eAAe,IAAIb,MAAM,CAACc,eAAe;EAChE,MAAMC,SAAS,GAAGH,OAAO,GACrBZ,MAAM,CAACa,eAAe,CAAEG,OAAO,CAAC,WAAW,EAAE,GAAGhB,MAAM,CAACc,eAAe,GAAG,CAAC,GAC1EG,SAAS;EAEb,oBACEpB,KAAA,CAACL,KAAK;IAAA0B,QAAA,GACHH,SAAS,iBACRpB,IAAA,CAACJ,IAAI;MACHc,CAAC,EAAED,IAAI,CAACC,CAAE;MACVG,CAAC,EAAEJ,IAAI,CAACI,CAAE;MACVC,KAAK,EAAEL,IAAI,CAACK,KAAM;MAClBE,MAAM,EAAEP,IAAI,CAACO,MAAO;MACpBQ,KAAK,EAAEJ,SAAU;MACjBK,KAAK,EAAC;IAAM,CACb,CACF,eACDzB,IAAA,CAACJ,IAAI;MACHc,CAAC,EAAED,IAAI,CAACC,CAAE;MACVG,CAAC,EAAEJ,IAAI,CAACI,CAAE;MACVC,KAAK,EAAEL,IAAI,CAACK,KAAM;MAClBE,MAAM,EAAEP,IAAI,CAACO,MAAO;MACpBQ,KAAK,EAAEnB,MAAM,CAACmB,KAAM;MACpBC,KAAK,EAAC,QAAQ;MACdC,WAAW,EAAErB,MAAM,CAACsB;IAAU,CAC/B,CAAC;EAAA,CACG,CAAC;AAEZ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
|
+
import { Path } from "@shopify/react-native-skia";
|
|
5
|
+
import { denormalizePoints } from "../utils/coordinates";
|
|
6
|
+
import { buildSmoothedPath } from "../utils/smoothing";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
export const FreehandRenderer = /*#__PURE__*/React.memo(function FreehandRenderer({
|
|
9
|
+
object,
|
|
10
|
+
canvasSize
|
|
11
|
+
}) {
|
|
12
|
+
const pathString = useMemo(() => {
|
|
13
|
+
const denormalized = denormalizePoints(object.points, canvasSize);
|
|
14
|
+
return buildSmoothedPath(denormalized);
|
|
15
|
+
}, [object.points, canvasSize]);
|
|
16
|
+
if (!pathString) return null;
|
|
17
|
+
return /*#__PURE__*/_jsx(Path, {
|
|
18
|
+
path: pathString,
|
|
19
|
+
style: "stroke",
|
|
20
|
+
strokeWidth: object.lineWidth,
|
|
21
|
+
color: object.color,
|
|
22
|
+
strokeCap: "round",
|
|
23
|
+
strokeJoin: "round"
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=FreehandRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useMemo","Path","denormalizePoints","buildSmoothedPath","jsx","_jsx","FreehandRenderer","memo","object","canvasSize","pathString","denormalized","points","path","style","strokeWidth","lineWidth","color","strokeCap","strokeJoin"],"sourceRoot":"../../../src","sources":["renderers/FreehandRenderer.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,IAAI,QAAQ,4BAA4B;AAEjD,SAASC,iBAAiB,QAAQ,sBAAsB;AACxD,SAASC,iBAAiB,QAAQ,oBAAoB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAOvD,OAAO,MAAMC,gBAAgB,gBAAGP,KAAK,CAACQ,IAAI,CAAC,SAASD,gBAAgBA,CAAC;EACnEE,MAAM;EACNC;AACqB,CAAC,EAAE;EACxB,MAAMC,UAAU,GAAGV,OAAO,CAAC,MAAM;IAC/B,MAAMW,YAAY,GAAGT,iBAAiB,CAACM,MAAM,CAACI,MAAM,EAAEH,UAAU,CAAC;IACjE,OAAON,iBAAiB,CAACQ,YAAY,CAAC;EACxC,CAAC,EAAE,CAACH,MAAM,CAACI,MAAM,EAAEH,UAAU,CAAC,CAAC;EAE/B,IAAI,CAACC,UAAU,EAAE,OAAO,IAAI;EAE5B,oBACEL,IAAA,CAACJ,IAAI;IACHY,IAAI,EAAEH,UAAW;IACjBI,KAAK,EAAC,QAAQ;IACdC,WAAW,EAAEP,MAAM,CAACQ,SAAU;IAC9BC,KAAK,EAAET,MAAM,CAACS,KAAM;IACpBC,SAAS,EAAC,OAAO;IACjBC,UAAU,EAAC;EAAO,CACnB,CAAC;AAEN,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Path, Line as SkiaLine, Rect, Oval, Group, Skia } from "@shopify/react-native-skia";
|
|
5
|
+
import { useDerivedValue } from "react-native-reanimated";
|
|
6
|
+
|
|
7
|
+
// ─── Freehand In-Progress ────────────────────────────────────────────────────
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
// Empty path constant used as fallback when not drawing
|
|
10
|
+
const EMPTY_PATH = Skia.Path.Make();
|
|
11
|
+
export const FreehandInProgress = /*#__PURE__*/React.memo(function FreehandInProgress({
|
|
12
|
+
path,
|
|
13
|
+
color,
|
|
14
|
+
lineWidth
|
|
15
|
+
}) {
|
|
16
|
+
const safePath = useDerivedValue(() => path.value ?? EMPTY_PATH);
|
|
17
|
+
return /*#__PURE__*/_jsx(Path, {
|
|
18
|
+
path: safePath,
|
|
19
|
+
style: "stroke",
|
|
20
|
+
strokeWidth: lineWidth,
|
|
21
|
+
color: color,
|
|
22
|
+
strokeCap: "round",
|
|
23
|
+
strokeJoin: "round"
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// ─── Polygon In-Progress ─────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
const POLYGON_VERTEX_RADIUS = 8;
|
|
30
|
+
const POLYGON_VERTEX_COLOR = "rgba(0, 122, 255, 0.8)";
|
|
31
|
+
export const PolygonInProgress = /*#__PURE__*/React.memo(function PolygonInProgress({
|
|
32
|
+
pointsFlat,
|
|
33
|
+
pointCount
|
|
34
|
+
}) {
|
|
35
|
+
// Build a path of circles at each vertex using a derived path with addCircle
|
|
36
|
+
const verticesPath = useDerivedValue(() => {
|
|
37
|
+
const p = Skia.Path.Make();
|
|
38
|
+
const count = pointCount.value;
|
|
39
|
+
const flat = pointsFlat.value;
|
|
40
|
+
for (let i = 0; i < count; i++) {
|
|
41
|
+
const cx = flat[i * 2];
|
|
42
|
+
const cy = flat[i * 2 + 1];
|
|
43
|
+
p.addCircle(cx, cy, POLYGON_VERTEX_RADIUS);
|
|
44
|
+
}
|
|
45
|
+
return p;
|
|
46
|
+
});
|
|
47
|
+
return /*#__PURE__*/_jsx(Path, {
|
|
48
|
+
path: verticesPath,
|
|
49
|
+
style: "fill",
|
|
50
|
+
color: POLYGON_VERTEX_COLOR
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ─── Shape In-Progress ───────────────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
export const ShapeInProgress = /*#__PURE__*/React.memo(function ShapeInProgress({
|
|
57
|
+
shapeType,
|
|
58
|
+
startX,
|
|
59
|
+
startY,
|
|
60
|
+
currentX,
|
|
61
|
+
currentY,
|
|
62
|
+
color,
|
|
63
|
+
lineWidth,
|
|
64
|
+
fillColor,
|
|
65
|
+
fillAlpha,
|
|
66
|
+
isDrawing
|
|
67
|
+
}) {
|
|
68
|
+
// Hide when not actively drawing (prevents ghost shapes when switching tools)
|
|
69
|
+
const opacity = useDerivedValue(() => isDrawing.value ? 1 : 0);
|
|
70
|
+
|
|
71
|
+
// Derived values for the shape bounds
|
|
72
|
+
const x = useDerivedValue(() => Math.min(startX.value, currentX.value));
|
|
73
|
+
const y = useDerivedValue(() => Math.min(startY.value, currentY.value));
|
|
74
|
+
const width = useDerivedValue(() => Math.abs(currentX.value - startX.value));
|
|
75
|
+
const height = useDerivedValue(() => Math.abs(currentY.value - startY.value));
|
|
76
|
+
|
|
77
|
+
// Derived point values for Line-based shapes
|
|
78
|
+
const p1 = useDerivedValue(() => ({
|
|
79
|
+
x: startX.value,
|
|
80
|
+
y: startY.value
|
|
81
|
+
}));
|
|
82
|
+
const p2 = useDerivedValue(() => ({
|
|
83
|
+
x: currentX.value,
|
|
84
|
+
y: currentY.value
|
|
85
|
+
}));
|
|
86
|
+
const resolvedFillColor = useDerivedValue(() => {
|
|
87
|
+
if (!fillColor.value || !isDrawing.value) return "transparent";
|
|
88
|
+
return fillColor.value.replace(/[\d.]+\)$/, `${fillAlpha.value})`);
|
|
89
|
+
});
|
|
90
|
+
switch (shapeType) {
|
|
91
|
+
case "line":
|
|
92
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
93
|
+
opacity: opacity,
|
|
94
|
+
children: /*#__PURE__*/_jsx(SkiaLine, {
|
|
95
|
+
p1: p1,
|
|
96
|
+
p2: p2,
|
|
97
|
+
color: color,
|
|
98
|
+
style: "stroke",
|
|
99
|
+
strokeWidth: lineWidth,
|
|
100
|
+
strokeCap: "round"
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
case "arrow":
|
|
104
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
105
|
+
opacity: opacity,
|
|
106
|
+
children: /*#__PURE__*/_jsx(SkiaLine, {
|
|
107
|
+
p1: p1,
|
|
108
|
+
p2: p2,
|
|
109
|
+
color: color,
|
|
110
|
+
style: "stroke",
|
|
111
|
+
strokeWidth: lineWidth,
|
|
112
|
+
strokeCap: "round"
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
case "rectangle":
|
|
116
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
117
|
+
opacity: opacity,
|
|
118
|
+
children: [/*#__PURE__*/_jsx(Rect, {
|
|
119
|
+
x: x,
|
|
120
|
+
y: y,
|
|
121
|
+
width: width,
|
|
122
|
+
height: height,
|
|
123
|
+
color: resolvedFillColor,
|
|
124
|
+
style: "fill"
|
|
125
|
+
}), /*#__PURE__*/_jsx(Rect, {
|
|
126
|
+
x: x,
|
|
127
|
+
y: y,
|
|
128
|
+
width: width,
|
|
129
|
+
height: height,
|
|
130
|
+
color: color,
|
|
131
|
+
style: "stroke",
|
|
132
|
+
strokeWidth: lineWidth
|
|
133
|
+
})]
|
|
134
|
+
});
|
|
135
|
+
case "circle":
|
|
136
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
137
|
+
opacity: opacity,
|
|
138
|
+
children: [/*#__PURE__*/_jsx(Oval, {
|
|
139
|
+
x: x,
|
|
140
|
+
y: y,
|
|
141
|
+
width: width,
|
|
142
|
+
height: height,
|
|
143
|
+
color: resolvedFillColor,
|
|
144
|
+
style: "fill"
|
|
145
|
+
}), /*#__PURE__*/_jsx(Oval, {
|
|
146
|
+
x: x,
|
|
147
|
+
y: y,
|
|
148
|
+
width: width,
|
|
149
|
+
height: height,
|
|
150
|
+
color: color,
|
|
151
|
+
style: "stroke",
|
|
152
|
+
strokeWidth: lineWidth
|
|
153
|
+
})]
|
|
154
|
+
});
|
|
155
|
+
case "measure":
|
|
156
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
157
|
+
opacity: opacity,
|
|
158
|
+
children: /*#__PURE__*/_jsx(SkiaLine, {
|
|
159
|
+
p1: p1,
|
|
160
|
+
p2: p2,
|
|
161
|
+
color: color,
|
|
162
|
+
style: "stroke",
|
|
163
|
+
strokeWidth: lineWidth,
|
|
164
|
+
strokeCap: "round"
|
|
165
|
+
})
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=InProgressRenderer.js.map
|