canvu-react 0.4.3 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/native.cjs +400 -5
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +79 -2
- package/dist/native.d.ts +79 -2
- package/dist/native.js +400 -7
- package/dist/native.js.map +1 -1
- package/dist/realtime.cjs +7 -0
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +7 -0
- package/dist/realtime.js.map +1 -1
- package/package.json +1 -1
package/dist/native.cjs
CHANGED
|
@@ -127,6 +127,13 @@ function getRotationHandleWorldPosition(bounds, rotationRad, handleOffsetWorld)
|
|
|
127
127
|
rotationRad
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
|
+
function rectFromCorners(a, b) {
|
|
131
|
+
const minX = Math.min(a.x, b.x);
|
|
132
|
+
const maxX = Math.max(a.x, b.x);
|
|
133
|
+
const minY = Math.min(a.y, b.y);
|
|
134
|
+
const maxY = Math.max(a.y, b.y);
|
|
135
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
136
|
+
}
|
|
130
137
|
|
|
131
138
|
// src/scene/freehand-path.ts
|
|
132
139
|
function smoothFreehandPointsToPathD(points) {
|
|
@@ -786,6 +793,15 @@ function createShapeId() {
|
|
|
786
793
|
const uid = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : String(Date.now());
|
|
787
794
|
return `user-shape-${uid}`;
|
|
788
795
|
}
|
|
796
|
+
function lineEndpointsToLocal(bounds, worldEndA, worldEndB) {
|
|
797
|
+
const b = normalizeRect(bounds);
|
|
798
|
+
return {
|
|
799
|
+
x1: worldEndA.x - b.x,
|
|
800
|
+
y1: worldEndA.y - b.y,
|
|
801
|
+
x2: worldEndB.x - b.x,
|
|
802
|
+
y2: worldEndB.y - b.y
|
|
803
|
+
};
|
|
804
|
+
}
|
|
789
805
|
function rebuildItemSvg(item) {
|
|
790
806
|
const style = resolveStrokeStyle(item);
|
|
791
807
|
const k = item.toolKind;
|
|
@@ -889,6 +905,85 @@ function rebuildItemSvg(item) {
|
|
|
889
905
|
}
|
|
890
906
|
return item;
|
|
891
907
|
}
|
|
908
|
+
function createRectangleItem(id, bounds, style) {
|
|
909
|
+
const r = normalizeRect(bounds);
|
|
910
|
+
const s = { ...DEFAULT_STROKE_STYLE, ...style };
|
|
911
|
+
return rebuildItemSvg({
|
|
912
|
+
id,
|
|
913
|
+
x: r.x,
|
|
914
|
+
y: r.y,
|
|
915
|
+
bounds: { ...r },
|
|
916
|
+
toolKind: "rect",
|
|
917
|
+
stroke: s.stroke,
|
|
918
|
+
strokeWidth: s.strokeWidth,
|
|
919
|
+
...s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {},
|
|
920
|
+
childrenSvg: ""
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
function createEllipseItem(id, bounds, style) {
|
|
924
|
+
const r = normalizeRect(bounds);
|
|
925
|
+
const s = { ...DEFAULT_STROKE_STYLE, ...style };
|
|
926
|
+
return rebuildItemSvg({
|
|
927
|
+
id,
|
|
928
|
+
x: r.x,
|
|
929
|
+
y: r.y,
|
|
930
|
+
bounds: { ...r },
|
|
931
|
+
toolKind: "ellipse",
|
|
932
|
+
stroke: s.stroke,
|
|
933
|
+
strokeWidth: s.strokeWidth,
|
|
934
|
+
...s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {},
|
|
935
|
+
childrenSvg: ""
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
function createArchitecturalCloudItem(id, bounds, style) {
|
|
939
|
+
const r = normalizeRect(bounds);
|
|
940
|
+
const s = { ...DEFAULT_STROKE_STYLE, ...style };
|
|
941
|
+
return rebuildItemSvg({
|
|
942
|
+
id,
|
|
943
|
+
x: r.x,
|
|
944
|
+
y: r.y,
|
|
945
|
+
bounds: { ...r },
|
|
946
|
+
toolKind: "architectural-cloud",
|
|
947
|
+
stroke: s.stroke,
|
|
948
|
+
strokeWidth: s.strokeWidth,
|
|
949
|
+
...s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {},
|
|
950
|
+
childrenSvg: ""
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
function createLineItem(id, bounds, line, toolKind, style, arrowBind) {
|
|
954
|
+
const r = normalizeRect(bounds);
|
|
955
|
+
const s = { ...DEFAULT_STROKE_STYLE, ...style };
|
|
956
|
+
return rebuildItemSvg({
|
|
957
|
+
id,
|
|
958
|
+
x: r.x,
|
|
959
|
+
y: r.y,
|
|
960
|
+
bounds: { ...r },
|
|
961
|
+
toolKind,
|
|
962
|
+
line: { ...line },
|
|
963
|
+
stroke: s.stroke,
|
|
964
|
+
strokeWidth: s.strokeWidth,
|
|
965
|
+
...s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {},
|
|
966
|
+
...{},
|
|
967
|
+
childrenSvg: ""
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
function createTextItem(id, bounds, text = "", style, textFontSize) {
|
|
971
|
+
const r = normalizeRect(bounds);
|
|
972
|
+
const s = { ...DEFAULT_STROKE_STYLE, ...style };
|
|
973
|
+
return rebuildItemSvg({
|
|
974
|
+
id,
|
|
975
|
+
x: r.x,
|
|
976
|
+
y: r.y,
|
|
977
|
+
bounds: { ...r },
|
|
978
|
+
toolKind: "text",
|
|
979
|
+
text,
|
|
980
|
+
stroke: s.stroke,
|
|
981
|
+
strokeWidth: s.strokeWidth,
|
|
982
|
+
...s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {},
|
|
983
|
+
...{ textFontSize } ,
|
|
984
|
+
childrenSvg: ""
|
|
985
|
+
});
|
|
986
|
+
}
|
|
892
987
|
function createFreehandStrokeItem(id, pointsWorld, toolKind, style) {
|
|
893
988
|
if (pointsWorld.length === 0) return null;
|
|
894
989
|
const merged = {
|
|
@@ -1771,9 +1866,9 @@ function NativeInteractionOverlay({
|
|
|
1771
1866
|
const previewElements = react.useMemo(() => {
|
|
1772
1867
|
if (!placementPreview) return null;
|
|
1773
1868
|
const p = placementPreview;
|
|
1774
|
-
if (p.kind === "rect" || p.kind === "ellipse") {
|
|
1869
|
+
if (p.kind === "rect" || p.kind === "ellipse" || p.kind === "architectural-cloud") {
|
|
1775
1870
|
const r = normalizeRect(p.rect);
|
|
1776
|
-
return p.kind === "rect" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1871
|
+
return p.kind === "rect" || p.kind === "architectural-cloud" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1777
1872
|
reactNativeSkia.Rect,
|
|
1778
1873
|
{
|
|
1779
1874
|
x: r.x,
|
|
@@ -2105,6 +2200,171 @@ function NativeSceneRenderer({
|
|
|
2105
2200
|
if (width <= 0 || height <= 0) return null;
|
|
2106
2201
|
return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Canvas, { style: { width, height }, children: /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: cameraTransform, children: visible.map((item) => /* @__PURE__ */ jsxRuntime.jsx(MemoShape, { item }, item.id)) }) });
|
|
2107
2202
|
}
|
|
2203
|
+
var DEFAULT_NATIVE_VECTOR_TOOLS = [
|
|
2204
|
+
{ id: "hand", label: "Hand", shortLabel: "H" },
|
|
2205
|
+
{ id: "select", label: "Select", shortLabel: "V" },
|
|
2206
|
+
{ id: "draw", label: "Draw", shortLabel: "D" },
|
|
2207
|
+
{ id: "marker", label: "Marker", shortLabel: "M" },
|
|
2208
|
+
{ id: "eraser", label: "Eraser", shortLabel: "E" },
|
|
2209
|
+
{ id: "text", label: "Text", shortLabel: "T" },
|
|
2210
|
+
{ id: "note", label: "Note", shortLabel: "N" },
|
|
2211
|
+
{ id: "rect", label: "Rectangle", shortLabel: "R" },
|
|
2212
|
+
{ id: "ellipse", label: "Ellipse", shortLabel: "O" },
|
|
2213
|
+
{ id: "architectural-cloud", label: "Cloud", shortLabel: "C" },
|
|
2214
|
+
{ id: "line", label: "Line", shortLabel: "L" },
|
|
2215
|
+
{ id: "arrow", label: "Arrow", shortLabel: "A" }
|
|
2216
|
+
];
|
|
2217
|
+
function NativeVectorToolbar({
|
|
2218
|
+
value,
|
|
2219
|
+
onChange,
|
|
2220
|
+
tools = DEFAULT_NATIVE_VECTOR_TOOLS,
|
|
2221
|
+
disabled = false,
|
|
2222
|
+
disabledToolIds = [],
|
|
2223
|
+
accessibilityLabel = "Canvas tools",
|
|
2224
|
+
style,
|
|
2225
|
+
contentContainerStyle,
|
|
2226
|
+
toolButtonStyle,
|
|
2227
|
+
activeToolButtonStyle,
|
|
2228
|
+
toolLabelStyle,
|
|
2229
|
+
activeToolLabelStyle,
|
|
2230
|
+
renderToolIcon,
|
|
2231
|
+
renderToolButton
|
|
2232
|
+
}) {
|
|
2233
|
+
const disabledIds = react.useMemo(() => new Set(disabledToolIds), [disabledToolIds]);
|
|
2234
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { accessibilityLabel, style: [styles.shell, style], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2235
|
+
reactNative.ScrollView,
|
|
2236
|
+
{
|
|
2237
|
+
horizontal: true,
|
|
2238
|
+
showsHorizontalScrollIndicator: false,
|
|
2239
|
+
contentContainerStyle: [styles.content, contentContainerStyle],
|
|
2240
|
+
children: tools.map((tool) => {
|
|
2241
|
+
const selected = tool.id === value;
|
|
2242
|
+
const toolDisabled = disabled || tool.disabled || disabledIds.has(tool.id);
|
|
2243
|
+
const foregroundColor = selected ? "#fafaf9" : "#18181b";
|
|
2244
|
+
const onSelect = () => {
|
|
2245
|
+
if (!toolDisabled) {
|
|
2246
|
+
onChange(tool.id);
|
|
2247
|
+
}
|
|
2248
|
+
};
|
|
2249
|
+
const input = {
|
|
2250
|
+
tool,
|
|
2251
|
+
selected,
|
|
2252
|
+
disabled: toolDisabled,
|
|
2253
|
+
foregroundColor,
|
|
2254
|
+
onSelect
|
|
2255
|
+
};
|
|
2256
|
+
if (renderToolButton) {
|
|
2257
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { children: renderToolButton(input) }, tool.id);
|
|
2258
|
+
}
|
|
2259
|
+
const icon = renderToolIcon?.(input) ?? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2260
|
+
reactNative.Text,
|
|
2261
|
+
{
|
|
2262
|
+
style: [
|
|
2263
|
+
styles.shortLabel,
|
|
2264
|
+
{ color: foregroundColor },
|
|
2265
|
+
toolLabelStyle,
|
|
2266
|
+
selected ? activeToolLabelStyle : void 0
|
|
2267
|
+
],
|
|
2268
|
+
children: tool.shortLabel ?? tool.label.slice(0, 1).toUpperCase()
|
|
2269
|
+
}
|
|
2270
|
+
);
|
|
2271
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2272
|
+
reactNative.Pressable,
|
|
2273
|
+
{
|
|
2274
|
+
accessibilityLabel: tool.accessibilityLabel ?? tool.label,
|
|
2275
|
+
accessibilityRole: "button",
|
|
2276
|
+
accessibilityState: { selected, disabled: toolDisabled },
|
|
2277
|
+
disabled: toolDisabled,
|
|
2278
|
+
onPress: onSelect,
|
|
2279
|
+
style: ({ pressed }) => [
|
|
2280
|
+
styles.toolButton,
|
|
2281
|
+
toolButtonStyle,
|
|
2282
|
+
selected ? styles.activeToolButton : void 0,
|
|
2283
|
+
selected ? activeToolButtonStyle : void 0,
|
|
2284
|
+
pressed && !toolDisabled ? styles.pressedToolButton : void 0,
|
|
2285
|
+
toolDisabled ? styles.disabledToolButton : void 0
|
|
2286
|
+
],
|
|
2287
|
+
children: [
|
|
2288
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.iconSlot, children: icon }),
|
|
2289
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2290
|
+
reactNative.Text,
|
|
2291
|
+
{
|
|
2292
|
+
numberOfLines: 1,
|
|
2293
|
+
style: [
|
|
2294
|
+
styles.toolLabel,
|
|
2295
|
+
{ color: foregroundColor },
|
|
2296
|
+
toolLabelStyle,
|
|
2297
|
+
selected ? activeToolLabelStyle : void 0
|
|
2298
|
+
],
|
|
2299
|
+
children: tool.label
|
|
2300
|
+
}
|
|
2301
|
+
)
|
|
2302
|
+
]
|
|
2303
|
+
},
|
|
2304
|
+
tool.id
|
|
2305
|
+
);
|
|
2306
|
+
})
|
|
2307
|
+
}
|
|
2308
|
+
) });
|
|
2309
|
+
}
|
|
2310
|
+
var styles = reactNative.StyleSheet.create({
|
|
2311
|
+
shell: {
|
|
2312
|
+
borderRadius: 10,
|
|
2313
|
+
borderWidth: reactNative.StyleSheet.hairlineWidth,
|
|
2314
|
+
borderColor: "rgba(24, 24, 27, 0.14)",
|
|
2315
|
+
backgroundColor: "rgba(255, 255, 255, 0.96)",
|
|
2316
|
+
shadowColor: "#18181b",
|
|
2317
|
+
shadowOpacity: 0.12,
|
|
2318
|
+
shadowRadius: 16,
|
|
2319
|
+
shadowOffset: { width: 0, height: 8 },
|
|
2320
|
+
elevation: 6
|
|
2321
|
+
},
|
|
2322
|
+
content: {
|
|
2323
|
+
alignItems: "center",
|
|
2324
|
+
gap: 6,
|
|
2325
|
+
paddingHorizontal: 6,
|
|
2326
|
+
paddingVertical: 6
|
|
2327
|
+
},
|
|
2328
|
+
toolButton: {
|
|
2329
|
+
minWidth: 58,
|
|
2330
|
+
height: 52,
|
|
2331
|
+
alignItems: "center",
|
|
2332
|
+
justifyContent: "center",
|
|
2333
|
+
gap: 3,
|
|
2334
|
+
borderRadius: 8,
|
|
2335
|
+
paddingHorizontal: 8,
|
|
2336
|
+
borderWidth: reactNative.StyleSheet.hairlineWidth,
|
|
2337
|
+
borderColor: "transparent",
|
|
2338
|
+
backgroundColor: "transparent"
|
|
2339
|
+
},
|
|
2340
|
+
activeToolButton: {
|
|
2341
|
+
borderColor: "rgba(24, 24, 27, 0.24)",
|
|
2342
|
+
backgroundColor: "#18181b"
|
|
2343
|
+
},
|
|
2344
|
+
pressedToolButton: {
|
|
2345
|
+
backgroundColor: "rgba(24, 24, 27, 0.08)"
|
|
2346
|
+
},
|
|
2347
|
+
disabledToolButton: {
|
|
2348
|
+
opacity: 0.42
|
|
2349
|
+
},
|
|
2350
|
+
iconSlot: {
|
|
2351
|
+
height: 22,
|
|
2352
|
+
minWidth: 22,
|
|
2353
|
+
alignItems: "center",
|
|
2354
|
+
justifyContent: "center"
|
|
2355
|
+
},
|
|
2356
|
+
shortLabel: {
|
|
2357
|
+
fontSize: 16,
|
|
2358
|
+
fontWeight: "700",
|
|
2359
|
+
lineHeight: 20
|
|
2360
|
+
},
|
|
2361
|
+
toolLabel: {
|
|
2362
|
+
maxWidth: 68,
|
|
2363
|
+
fontSize: 10,
|
|
2364
|
+
fontWeight: "600",
|
|
2365
|
+
lineHeight: 12
|
|
2366
|
+
}
|
|
2367
|
+
});
|
|
2108
2368
|
|
|
2109
2369
|
// src/camera/camera.ts
|
|
2110
2370
|
var Camera2D = class {
|
|
@@ -2292,6 +2552,37 @@ function collectEraserTargetsAtWorldPoint(items, worldX, worldY, options) {
|
|
|
2292
2552
|
}
|
|
2293
2553
|
return ids;
|
|
2294
2554
|
}
|
|
2555
|
+
var MIN_PLACE_SIZE = 8;
|
|
2556
|
+
var MIN_ARROW_DRAG_PX = 8;
|
|
2557
|
+
var TAP_PX = 20;
|
|
2558
|
+
function isPlacementTool(toolId) {
|
|
2559
|
+
return toolId === "rect" || toolId === "ellipse" || toolId === "architectural-cloud" || toolId === "line" || toolId === "arrow";
|
|
2560
|
+
}
|
|
2561
|
+
function placementPreviewForTool(toolId, start, end) {
|
|
2562
|
+
if (toolId === "rect" || toolId === "ellipse" || toolId === "architectural-cloud") {
|
|
2563
|
+
return { kind: toolId, rect: rectFromCorners(start, end) };
|
|
2564
|
+
}
|
|
2565
|
+
return { kind: toolId, start, end };
|
|
2566
|
+
}
|
|
2567
|
+
function defaultPlacementWorld(toolId, center) {
|
|
2568
|
+
const cx = center.x;
|
|
2569
|
+
const cy = center.y;
|
|
2570
|
+
if (toolId === "rect") {
|
|
2571
|
+
return { raw: { x: cx - 60, y: cy - 40, width: 120, height: 80 } };
|
|
2572
|
+
}
|
|
2573
|
+
if (toolId === "ellipse") {
|
|
2574
|
+
return { raw: { x: cx - 70, y: cy - 45, width: 140, height: 90 } };
|
|
2575
|
+
}
|
|
2576
|
+
if (toolId === "architectural-cloud") {
|
|
2577
|
+
return { raw: { x: cx - 90, y: cy - 50, width: 180, height: 100 } };
|
|
2578
|
+
}
|
|
2579
|
+
const start = { x: cx - 50, y: cy };
|
|
2580
|
+
const end = { x: cx + 50, y: cy };
|
|
2581
|
+
return {
|
|
2582
|
+
raw: rectFromCorners(start, end),
|
|
2583
|
+
lineWorld: [start, end]
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2295
2586
|
function collectIdsInRect(items, marquee) {
|
|
2296
2587
|
const m = normalizeRect(marquee);
|
|
2297
2588
|
const out = [];
|
|
@@ -2469,10 +2760,31 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
2469
2760
|
setEraserPreviewIds(Array.from(eraserPreviewIdSetRef.current));
|
|
2470
2761
|
return;
|
|
2471
2762
|
}
|
|
2763
|
+
if (isPlacementTool(tool)) {
|
|
2764
|
+
dragStateRef.current = {
|
|
2765
|
+
kind: "place",
|
|
2766
|
+
tool,
|
|
2767
|
+
startWorld: { x: worldX, y: worldY },
|
|
2768
|
+
startScreen: { x: sx, y: sy }
|
|
2769
|
+
};
|
|
2770
|
+
setPlacementPreview(
|
|
2771
|
+
placementPreviewForTool(
|
|
2772
|
+
tool,
|
|
2773
|
+
{ x: worldX, y: worldY },
|
|
2774
|
+
{
|
|
2775
|
+
x: worldX,
|
|
2776
|
+
y: worldY
|
|
2777
|
+
}
|
|
2778
|
+
)
|
|
2779
|
+
);
|
|
2780
|
+
return;
|
|
2781
|
+
}
|
|
2472
2782
|
if (tool === "note" || tool === "text") {
|
|
2473
2783
|
dragStateRef.current = {
|
|
2474
2784
|
kind: "tap",
|
|
2475
|
-
|
|
2785
|
+
tool,
|
|
2786
|
+
startWorld: { x: worldX, y: worldY },
|
|
2787
|
+
startScreen: { x: sx, y: sy }
|
|
2476
2788
|
};
|
|
2477
2789
|
return;
|
|
2478
2790
|
}
|
|
@@ -2584,6 +2896,15 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
2584
2896
|
setEraserPreviewIds(Array.from(eraserPreviewIdSetRef.current));
|
|
2585
2897
|
return;
|
|
2586
2898
|
}
|
|
2899
|
+
if (st.kind === "place") {
|
|
2900
|
+
setPlacementPreview(
|
|
2901
|
+
placementPreviewForTool(st.tool, st.startWorld, {
|
|
2902
|
+
x: worldX,
|
|
2903
|
+
y: worldY
|
|
2904
|
+
})
|
|
2905
|
+
);
|
|
2906
|
+
return;
|
|
2907
|
+
}
|
|
2587
2908
|
},
|
|
2588
2909
|
onPanResponderRelease: (evt) => {
|
|
2589
2910
|
lastPinchDist.current = null;
|
|
@@ -2639,12 +2960,83 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
2639
2960
|
dragStateRef.current = { kind: "idle" };
|
|
2640
2961
|
return;
|
|
2641
2962
|
}
|
|
2963
|
+
if (st.kind === "place") {
|
|
2964
|
+
dragStateRef.current = { kind: "idle" };
|
|
2965
|
+
setPlacementPreview(null);
|
|
2966
|
+
const change = onItemsChangeRef.current;
|
|
2967
|
+
if (!change) return;
|
|
2968
|
+
const { worldX, worldY } = screenToWorld(
|
|
2969
|
+
evt.nativeEvent.locationX,
|
|
2970
|
+
evt.nativeEvent.locationY
|
|
2971
|
+
);
|
|
2972
|
+
const a = st.startWorld;
|
|
2973
|
+
const b = { x: worldX, y: worldY };
|
|
2974
|
+
const screenDx = evt.nativeEvent.locationX - st.startScreen.x;
|
|
2975
|
+
const screenDy = evt.nativeEvent.locationY - st.startScreen.y;
|
|
2976
|
+
if (st.tool === "arrow" && Math.hypot(screenDx, screenDy) < MIN_ARROW_DRAG_PX) {
|
|
2977
|
+
return;
|
|
2978
|
+
}
|
|
2979
|
+
let raw = rectFromCorners(a, b);
|
|
2980
|
+
let br = normalizeRect(raw);
|
|
2981
|
+
let lineStart = a;
|
|
2982
|
+
let lineEnd = b;
|
|
2983
|
+
if (br.width < MIN_PLACE_SIZE || br.height < MIN_PLACE_SIZE) {
|
|
2984
|
+
const center = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
2985
|
+
const defaults = defaultPlacementWorld(st.tool, center);
|
|
2986
|
+
raw = defaults.raw;
|
|
2987
|
+
br = normalizeRect(raw);
|
|
2988
|
+
if (defaults.lineWorld) {
|
|
2989
|
+
const [defaultStart, defaultEnd] = defaults.lineWorld;
|
|
2990
|
+
lineStart = defaultStart;
|
|
2991
|
+
lineEnd = defaultEnd;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
const id = createShapeId();
|
|
2995
|
+
if (st.tool === "rect") {
|
|
2996
|
+
change([...itemsRef.current, createRectangleItem(id, raw)]);
|
|
2997
|
+
onSelectionChangeRef.current?.([id]);
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
if (st.tool === "ellipse") {
|
|
3001
|
+
change([...itemsRef.current, createEllipseItem(id, raw)]);
|
|
3002
|
+
onSelectionChangeRef.current?.([id]);
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
if (st.tool === "architectural-cloud") {
|
|
3006
|
+
change([...itemsRef.current, createArchitecturalCloudItem(id, raw)]);
|
|
3007
|
+
onSelectionChangeRef.current?.([id]);
|
|
3008
|
+
return;
|
|
3009
|
+
}
|
|
3010
|
+
const line = lineEndpointsToLocal(br, lineStart, lineEnd);
|
|
3011
|
+
change([...itemsRef.current, createLineItem(id, br, line, st.tool)]);
|
|
3012
|
+
onSelectionChangeRef.current?.([id]);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
2642
3015
|
if (st.kind === "tap") {
|
|
2643
3016
|
dragStateRef.current = { kind: "idle" };
|
|
3017
|
+
const screenDx = evt.nativeEvent.locationX - st.startScreen.x;
|
|
3018
|
+
const screenDy = evt.nativeEvent.locationY - st.startScreen.y;
|
|
3019
|
+
if (Math.hypot(screenDx, screenDy) > TAP_PX) return;
|
|
2644
3020
|
const change = onItemsChangeRef.current;
|
|
2645
3021
|
if (!change) return;
|
|
2646
|
-
|
|
2647
|
-
|
|
3022
|
+
if (st.tool === "text") {
|
|
3023
|
+
const id = createShapeId();
|
|
3024
|
+
const item = createTextItem(
|
|
3025
|
+
id,
|
|
3026
|
+
{
|
|
3027
|
+
x: st.startWorld.x - 4,
|
|
3028
|
+
y: st.startWorld.y - 18,
|
|
3029
|
+
width: 160,
|
|
3030
|
+
height: 26
|
|
3031
|
+
},
|
|
3032
|
+
"Text",
|
|
3033
|
+
void 0,
|
|
3034
|
+
18
|
|
3035
|
+
);
|
|
3036
|
+
change([...itemsRef.current, item]);
|
|
3037
|
+
onSelectionChangeRef.current?.([id]);
|
|
3038
|
+
}
|
|
3039
|
+
if (st.tool === "note") {
|
|
2648
3040
|
const id = createShapeId();
|
|
2649
3041
|
const note = {
|
|
2650
3042
|
id,
|
|
@@ -2660,6 +3052,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
2660
3052
|
toolKind: "custom"
|
|
2661
3053
|
};
|
|
2662
3054
|
change([...itemsRef.current, note]);
|
|
3055
|
+
onSelectionChangeRef.current?.([id]);
|
|
2663
3056
|
}
|
|
2664
3057
|
return;
|
|
2665
3058
|
}
|
|
@@ -2747,9 +3140,11 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
2747
3140
|
);
|
|
2748
3141
|
});
|
|
2749
3142
|
|
|
3143
|
+
exports.DEFAULT_NATIVE_VECTOR_TOOLS = DEFAULT_NATIVE_VECTOR_TOOLS;
|
|
2750
3144
|
exports.NativeInteractionOverlay = NativeInteractionOverlay;
|
|
2751
3145
|
exports.NativeSceneRenderer = NativeSceneRenderer;
|
|
2752
3146
|
exports.NativeShapeRenderer = NativeShapeRenderer;
|
|
3147
|
+
exports.NativeVectorToolbar = NativeVectorToolbar;
|
|
2753
3148
|
exports.NativeVectorViewport = NativeVectorViewport;
|
|
2754
3149
|
exports.parseSvgFragment = parseSvgFragment;
|
|
2755
3150
|
//# sourceMappingURL=native.cjs.map
|