canvu-react 0.4.33 → 0.4.34
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/chatbot.d.cts +2 -1
- package/dist/chatbot.d.ts +2 -1
- package/dist/native.cjs +239 -23
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +10 -1
- package/dist/native.d.ts +10 -1
- package/dist/native.js +240 -24
- package/dist/native.js.map +1 -1
- package/dist/react.d.cts +3 -2
- package/dist/react.d.ts +3 -2
- package/dist/realtime.cjs +18 -3
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +3 -2
- package/dist/realtime.d.ts +3 -2
- package/dist/realtime.js +18 -3
- package/dist/realtime.js.map +1 -1
- package/dist/realtimeNative.cjs +2124 -0
- package/dist/realtimeNative.cjs.map +1 -0
- package/dist/realtimeNative.d.cts +255 -0
- package/dist/realtimeNative.d.ts +255 -0
- package/dist/realtimeNative.js +2097 -0
- package/dist/realtimeNative.js.map +1 -0
- package/dist/types-B82WiQQh.d.ts +69 -0
- package/dist/types-BQUbxMgz.d.cts +69 -0
- package/dist/{types-UZYYwK-v.d.ts → types-DeDm865m.d.ts} +2 -67
- package/dist/{types-BS-YG8Hx.d.cts → types-NBYvslB-.d.cts} +2 -67
- package/package.json +7 -1
package/dist/native.d.cts
CHANGED
|
@@ -2,6 +2,7 @@ import { C as Camera2D, S as StrokeStyle } from './shape-builders-CKEMjivV.cjs';
|
|
|
2
2
|
export { o as createFreehandStrokeItem, q as createImageItem, t as createShapeId } from './shape-builders-CKEMjivV.cjs';
|
|
3
3
|
import { V as VectorSceneItem, R as Rect } from './types-BCCvY6ie.cjs';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import { R as RemotePresencePeer } from './types-BQUbxMgz.cjs';
|
|
5
6
|
import { StyleProp, ViewStyle, TextStyle } from 'react-native';
|
|
6
7
|
import * as react from 'react';
|
|
7
8
|
import { ReactNode } from 'react';
|
|
@@ -58,8 +59,9 @@ type NativeInteractionOverlayProps = {
|
|
|
58
59
|
readonly laserTrail?: readonly TimedTrailPoint[];
|
|
59
60
|
readonly eraserPreviewItems?: readonly VectorSceneItem[];
|
|
60
61
|
readonly previewStrokeStyle?: StrokeStyle;
|
|
62
|
+
readonly remotePresence?: readonly RemotePresencePeer[];
|
|
61
63
|
};
|
|
62
|
-
declare function NativeInteractionOverlay({ camera, width, height, selectedItems, showResizeHandles, placementPreview, eraserTrail, laserTrail, eraserPreviewItems, previewStrokeStyle, }: NativeInteractionOverlayProps): react_jsx_runtime.JSX.Element | null;
|
|
64
|
+
declare function NativeInteractionOverlay({ camera, width, height, selectedItems, showResizeHandles, placementPreview, eraserTrail, laserTrail, eraserPreviewItems, previewStrokeStyle, remotePresence, }: NativeInteractionOverlayProps): react_jsx_runtime.JSX.Element | null;
|
|
63
65
|
|
|
64
66
|
type NativeSceneRendererProps = {
|
|
65
67
|
readonly items: readonly VectorSceneItem[];
|
|
@@ -214,6 +216,7 @@ type NativeWorldPointerDownDetail = {
|
|
|
214
216
|
type NativeVectorViewportProps = {
|
|
215
217
|
readonly items: readonly VectorSceneItem[];
|
|
216
218
|
readonly selectedIds?: readonly string[];
|
|
219
|
+
readonly remotePresence?: readonly RemotePresencePeer[];
|
|
217
220
|
readonly toolId?: string;
|
|
218
221
|
readonly toolLocked?: boolean;
|
|
219
222
|
readonly interactive?: boolean;
|
|
@@ -221,6 +224,12 @@ type NativeVectorViewportProps = {
|
|
|
221
224
|
readonly onItemsChange?: (items: VectorSceneItem[]) => void;
|
|
222
225
|
readonly onToolChangeRequest?: (toolId: string) => void;
|
|
223
226
|
readonly onWorldPointerDown?: (detail: NativeWorldPointerDownDetail) => void;
|
|
227
|
+
readonly onWorldPointerMove?: (world: {
|
|
228
|
+
readonly x: number;
|
|
229
|
+
readonly y: number;
|
|
230
|
+
}) => void;
|
|
231
|
+
readonly onWorldPointerLeave?: () => void;
|
|
232
|
+
readonly onPlacementPreviewChange?: (preview: PlacementPreview | null) => void;
|
|
224
233
|
readonly onCameraChange?: () => void;
|
|
225
234
|
readonly customPlacement?: NativeCustomShapePlacementOptions;
|
|
226
235
|
readonly customPlacements?: readonly NativeCustomShapePlacementOptions[];
|
package/dist/native.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { C as Camera2D, S as StrokeStyle } from './shape-builders-Cyh8zvDG.js';
|
|
|
2
2
|
export { o as createFreehandStrokeItem, q as createImageItem, t as createShapeId } from './shape-builders-Cyh8zvDG.js';
|
|
3
3
|
import { V as VectorSceneItem, R as Rect } from './types-BCCvY6ie.js';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import { R as RemotePresencePeer } from './types-B82WiQQh.js';
|
|
5
6
|
import { StyleProp, ViewStyle, TextStyle } from 'react-native';
|
|
6
7
|
import * as react from 'react';
|
|
7
8
|
import { ReactNode } from 'react';
|
|
@@ -58,8 +59,9 @@ type NativeInteractionOverlayProps = {
|
|
|
58
59
|
readonly laserTrail?: readonly TimedTrailPoint[];
|
|
59
60
|
readonly eraserPreviewItems?: readonly VectorSceneItem[];
|
|
60
61
|
readonly previewStrokeStyle?: StrokeStyle;
|
|
62
|
+
readonly remotePresence?: readonly RemotePresencePeer[];
|
|
61
63
|
};
|
|
62
|
-
declare function NativeInteractionOverlay({ camera, width, height, selectedItems, showResizeHandles, placementPreview, eraserTrail, laserTrail, eraserPreviewItems, previewStrokeStyle, }: NativeInteractionOverlayProps): react_jsx_runtime.JSX.Element | null;
|
|
64
|
+
declare function NativeInteractionOverlay({ camera, width, height, selectedItems, showResizeHandles, placementPreview, eraserTrail, laserTrail, eraserPreviewItems, previewStrokeStyle, remotePresence, }: NativeInteractionOverlayProps): react_jsx_runtime.JSX.Element | null;
|
|
63
65
|
|
|
64
66
|
type NativeSceneRendererProps = {
|
|
65
67
|
readonly items: readonly VectorSceneItem[];
|
|
@@ -214,6 +216,7 @@ type NativeWorldPointerDownDetail = {
|
|
|
214
216
|
type NativeVectorViewportProps = {
|
|
215
217
|
readonly items: readonly VectorSceneItem[];
|
|
216
218
|
readonly selectedIds?: readonly string[];
|
|
219
|
+
readonly remotePresence?: readonly RemotePresencePeer[];
|
|
217
220
|
readonly toolId?: string;
|
|
218
221
|
readonly toolLocked?: boolean;
|
|
219
222
|
readonly interactive?: boolean;
|
|
@@ -221,6 +224,12 @@ type NativeVectorViewportProps = {
|
|
|
221
224
|
readonly onItemsChange?: (items: VectorSceneItem[]) => void;
|
|
222
225
|
readonly onToolChangeRequest?: (toolId: string) => void;
|
|
223
226
|
readonly onWorldPointerDown?: (detail: NativeWorldPointerDownDetail) => void;
|
|
227
|
+
readonly onWorldPointerMove?: (world: {
|
|
228
|
+
readonly x: number;
|
|
229
|
+
readonly y: number;
|
|
230
|
+
}) => void;
|
|
231
|
+
readonly onWorldPointerLeave?: () => void;
|
|
232
|
+
readonly onPlacementPreviewChange?: (preview: PlacementPreview | null) => void;
|
|
224
233
|
readonly onCameraChange?: () => void;
|
|
225
234
|
readonly customPlacement?: NativeCustomShapePlacementOptions;
|
|
226
235
|
readonly customPlacements?: readonly NativeCustomShapePlacementOptions[];
|
package/dist/native.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import getStroke from 'perfect-freehand';
|
|
2
2
|
import { Group, Canvas, Rect, Circle, Path, RoundedRect, Oval, DashPathEffect, Line, vec, matchFont, Text, useImage, Image } from '@shopify/react-native-skia';
|
|
3
|
-
import { memo, forwardRef, useState, useRef,
|
|
3
|
+
import { memo, forwardRef, useState, useRef, useCallback, useEffect, useMemo, useImperativeHandle } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import { StyleSheet, PanResponder, View, Pressable, Text as Text$1, ScrollView } from 'react-native';
|
|
6
6
|
|
|
@@ -1354,6 +1354,17 @@ function computeResizeBoundsFixedAspect(bounds, handle, currentWorld, aspect) {
|
|
|
1354
1354
|
}
|
|
1355
1355
|
}
|
|
1356
1356
|
|
|
1357
|
+
// src/react/presence/peer-color.ts
|
|
1358
|
+
function defaultPresenceColorForId(id) {
|
|
1359
|
+
let h = 2166136261;
|
|
1360
|
+
for (let i = 0; i < id.length; i++) {
|
|
1361
|
+
h ^= id.charCodeAt(i);
|
|
1362
|
+
h = Math.imul(h, 16777619);
|
|
1363
|
+
}
|
|
1364
|
+
const hue = (h >>> 0) % 360;
|
|
1365
|
+
return `hsl(${hue} 72% 42%)`;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1357
1368
|
// src/scene/freehand-path.ts
|
|
1358
1369
|
function smoothFreehandPointsToPathD(points) {
|
|
1359
1370
|
const n = points.length;
|
|
@@ -2272,6 +2283,26 @@ var HANDLE_ORDER = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
|
2272
2283
|
var ERASER_PREVIEW_OPACITY = 0.3;
|
|
2273
2284
|
var OVERLAY_STROKE_PX = 1.25;
|
|
2274
2285
|
var MARQUEE_DASH_PX = 4;
|
|
2286
|
+
var REMOTE_CURSOR_SCREEN_PX = 22;
|
|
2287
|
+
var REMOTE_LABEL_SCREEN_PX = 12;
|
|
2288
|
+
function remoteStrokePaint(tool, fallback) {
|
|
2289
|
+
if (tool === "laser") {
|
|
2290
|
+
return { stroke: LASER_TINT, strokeOpacity: 0.92, widthWorld: 4 };
|
|
2291
|
+
}
|
|
2292
|
+
if (tool === "marker") {
|
|
2293
|
+
return { stroke: fallback, strokeOpacity: 0.45, widthWorld: 14 };
|
|
2294
|
+
}
|
|
2295
|
+
if (tool === "brush") {
|
|
2296
|
+
return { stroke: fallback, strokeOpacity: 0.85, widthWorld: 5 };
|
|
2297
|
+
}
|
|
2298
|
+
if (tool === "pencil") {
|
|
2299
|
+
return { stroke: fallback, strokeOpacity: 0.9, widthWorld: 2.5 };
|
|
2300
|
+
}
|
|
2301
|
+
return { stroke: fallback, strokeOpacity: 0.95, widthWorld: 3.5 };
|
|
2302
|
+
}
|
|
2303
|
+
function isRemoteFreehandTool(tool) {
|
|
2304
|
+
return tool === "draw" || tool === "marker" || tool === "pencil" || tool === "brush";
|
|
2305
|
+
}
|
|
2275
2306
|
function pointsToSmoothPathD(points) {
|
|
2276
2307
|
if (points.length < 2) return null;
|
|
2277
2308
|
const d = smoothFreehandPointsToPathD(points);
|
|
@@ -2292,7 +2323,8 @@ function NativeInteractionOverlay({
|
|
|
2292
2323
|
eraserTrail,
|
|
2293
2324
|
laserTrail,
|
|
2294
2325
|
eraserPreviewItems = [],
|
|
2295
|
-
previewStrokeStyle
|
|
2326
|
+
previewStrokeStyle,
|
|
2327
|
+
remotePresence = []
|
|
2296
2328
|
}) {
|
|
2297
2329
|
const z = camera.zoom;
|
|
2298
2330
|
const camTransform = skiaCameraTransform(z, camera.x, camera.y);
|
|
@@ -2686,6 +2718,136 @@ function NativeInteractionOverlay({
|
|
|
2686
2718
|
)
|
|
2687
2719
|
] });
|
|
2688
2720
|
}, [laserTrail, z]);
|
|
2721
|
+
const remotePresenceElements = useMemo(() => {
|
|
2722
|
+
if (remotePresence.length === 0) return null;
|
|
2723
|
+
const labelFont = matchFont({ fontSize: REMOTE_LABEL_SCREEN_PX / z });
|
|
2724
|
+
const cursorSize = REMOTE_CURSOR_SCREEN_PX / z;
|
|
2725
|
+
const labelOffsetX = 14 / z;
|
|
2726
|
+
const labelOffsetY = 18 / z;
|
|
2727
|
+
return /* @__PURE__ */ jsx(Fragment, { children: remotePresence.map((peer) => {
|
|
2728
|
+
const color = peer.color ?? defaultPresenceColorForId(peer.id);
|
|
2729
|
+
const markup = peer.markupStroke;
|
|
2730
|
+
const cursor = peer.cursor;
|
|
2731
|
+
const camera2 = peer.camera;
|
|
2732
|
+
let strokeElement = null;
|
|
2733
|
+
if (markup && markup.points.length > 0) {
|
|
2734
|
+
const fallbackPaint = remoteStrokePaint(markup.tool, color);
|
|
2735
|
+
const paint = {
|
|
2736
|
+
stroke: markup.stroke ?? fallbackPaint.stroke,
|
|
2737
|
+
strokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,
|
|
2738
|
+
widthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld
|
|
2739
|
+
};
|
|
2740
|
+
if (markup.tool === "laser") {
|
|
2741
|
+
const d = markup.points.length >= 2 ? smoothFreehandPointsToPathD([...markup.points]) : null;
|
|
2742
|
+
if (d) {
|
|
2743
|
+
strokeElement = /* @__PURE__ */ jsx(
|
|
2744
|
+
Path,
|
|
2745
|
+
{
|
|
2746
|
+
path: d,
|
|
2747
|
+
color: colorWithOpacity(paint.stroke, paint.strokeOpacity),
|
|
2748
|
+
style: "stroke",
|
|
2749
|
+
strokeWidth: Math.max(paint.widthWorld, OVERLAY_STROKE_PX) / z,
|
|
2750
|
+
strokeCap: "round",
|
|
2751
|
+
strokeJoin: "round",
|
|
2752
|
+
antiAlias: true
|
|
2753
|
+
}
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
if (!strokeElement && isRemoteFreehandTool(markup.tool)) {
|
|
2758
|
+
const payload = computeFreehandSvgPayload(
|
|
2759
|
+
markup.points.map((point) => ({ x: point.x, y: point.y })),
|
|
2760
|
+
{
|
|
2761
|
+
stroke: paint.stroke,
|
|
2762
|
+
strokeWidth: paint.widthWorld,
|
|
2763
|
+
strokeOpacity: paint.strokeOpacity
|
|
2764
|
+
},
|
|
2765
|
+
markup.tool,
|
|
2766
|
+
markup.points.length === 2
|
|
2767
|
+
);
|
|
2768
|
+
if (payload?.kind === "circle") {
|
|
2769
|
+
strokeElement = /* @__PURE__ */ jsx(
|
|
2770
|
+
Circle,
|
|
2771
|
+
{
|
|
2772
|
+
cx: payload.cx,
|
|
2773
|
+
cy: payload.cy,
|
|
2774
|
+
r: payload.r,
|
|
2775
|
+
color: colorWithOpacity(payload.fill, payload.fillOpacity),
|
|
2776
|
+
style: "fill",
|
|
2777
|
+
antiAlias: true
|
|
2778
|
+
}
|
|
2779
|
+
);
|
|
2780
|
+
}
|
|
2781
|
+
if (payload?.kind === "fillPath") {
|
|
2782
|
+
strokeElement = /* @__PURE__ */ jsx(
|
|
2783
|
+
Path,
|
|
2784
|
+
{
|
|
2785
|
+
path: payload.d,
|
|
2786
|
+
color: colorWithOpacity(payload.fill, payload.fillOpacity),
|
|
2787
|
+
style: "fill",
|
|
2788
|
+
fillType: "winding",
|
|
2789
|
+
antiAlias: true
|
|
2790
|
+
}
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
if (payload?.kind === "strokePath") {
|
|
2794
|
+
strokeElement = /* @__PURE__ */ jsx(
|
|
2795
|
+
Path,
|
|
2796
|
+
{
|
|
2797
|
+
path: payload.d,
|
|
2798
|
+
color: colorWithOpacity(payload.stroke, payload.strokeOpacity),
|
|
2799
|
+
style: "stroke",
|
|
2800
|
+
strokeWidth: payload.strokeWidth,
|
|
2801
|
+
strokeCap: "round",
|
|
2802
|
+
strokeJoin: "round",
|
|
2803
|
+
antiAlias: true
|
|
2804
|
+
}
|
|
2805
|
+
);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
const cameraElement = camera2 ? /* @__PURE__ */ jsx(
|
|
2810
|
+
Rect,
|
|
2811
|
+
{
|
|
2812
|
+
x: -camera2.x / camera2.zoom,
|
|
2813
|
+
y: -camera2.y / camera2.zoom,
|
|
2814
|
+
width: camera2.viewportWidth / camera2.zoom,
|
|
2815
|
+
height: camera2.viewportHeight / camera2.zoom,
|
|
2816
|
+
color,
|
|
2817
|
+
style: "stroke",
|
|
2818
|
+
strokeWidth: overlayStrokeWorld,
|
|
2819
|
+
antiAlias: true,
|
|
2820
|
+
children: /* @__PURE__ */ jsx(DashPathEffect, { intervals: [marqueeDashWorld, marqueeDashWorld] })
|
|
2821
|
+
}
|
|
2822
|
+
) : null;
|
|
2823
|
+
const cursorElement = cursor ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2824
|
+
/* @__PURE__ */ jsx(
|
|
2825
|
+
Path,
|
|
2826
|
+
{
|
|
2827
|
+
path: `M ${cursor.x} ${cursor.y} L ${cursor.x + cursorSize} ${cursor.y + cursorSize * 0.34} L ${cursor.x + cursorSize * 0.42} ${cursor.y + cursorSize * 0.44} L ${cursor.x + cursorSize * 0.58} ${cursor.y + cursorSize} Z`,
|
|
2828
|
+
color,
|
|
2829
|
+
style: "fill",
|
|
2830
|
+
antiAlias: true
|
|
2831
|
+
}
|
|
2832
|
+
),
|
|
2833
|
+
peer.displayName ? /* @__PURE__ */ jsx(
|
|
2834
|
+
Text,
|
|
2835
|
+
{
|
|
2836
|
+
x: cursor.x + labelOffsetX,
|
|
2837
|
+
y: cursor.y + labelOffsetY,
|
|
2838
|
+
text: peer.displayName,
|
|
2839
|
+
color,
|
|
2840
|
+
font: labelFont
|
|
2841
|
+
}
|
|
2842
|
+
) : null
|
|
2843
|
+
] }) : null;
|
|
2844
|
+
return /* @__PURE__ */ jsxs(Group, { children: [
|
|
2845
|
+
cameraElement,
|
|
2846
|
+
strokeElement,
|
|
2847
|
+
cursorElement
|
|
2848
|
+
] }, peer.clientId ?? peer.id);
|
|
2849
|
+
}) });
|
|
2850
|
+
}, [remotePresence, z, overlayStrokeWorld, marqueeDashWorld]);
|
|
2689
2851
|
if (width <= 0 || height <= 0) return null;
|
|
2690
2852
|
return /* @__PURE__ */ jsx(
|
|
2691
2853
|
Canvas,
|
|
@@ -2703,6 +2865,7 @@ function NativeInteractionOverlay({
|
|
|
2703
2865
|
laserTrailElements,
|
|
2704
2866
|
eraserTrailElements,
|
|
2705
2867
|
eraserPreviewElements,
|
|
2868
|
+
remotePresenceElements,
|
|
2706
2869
|
selectionElements
|
|
2707
2870
|
] })
|
|
2708
2871
|
}
|
|
@@ -4205,6 +4368,7 @@ function fitCameraToWorldRect(camera, viewportW, viewportH, worldRect, padding)
|
|
|
4205
4368
|
var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
4206
4369
|
items,
|
|
4207
4370
|
selectedIds = [],
|
|
4371
|
+
remotePresence = [],
|
|
4208
4372
|
toolId = "hand",
|
|
4209
4373
|
toolLocked = false,
|
|
4210
4374
|
interactive = false,
|
|
@@ -4212,6 +4376,9 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4212
4376
|
onItemsChange,
|
|
4213
4377
|
onToolChangeRequest,
|
|
4214
4378
|
onWorldPointerDown,
|
|
4379
|
+
onWorldPointerMove,
|
|
4380
|
+
onWorldPointerLeave,
|
|
4381
|
+
onPlacementPreviewChange,
|
|
4215
4382
|
onCameraChange,
|
|
4216
4383
|
customPlacement,
|
|
4217
4384
|
customPlacements = [],
|
|
@@ -4229,6 +4396,12 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4229
4396
|
onToolChangeRequestRef.current = onToolChangeRequest;
|
|
4230
4397
|
const onWorldPointerDownRef = useRef(onWorldPointerDown);
|
|
4231
4398
|
onWorldPointerDownRef.current = onWorldPointerDown;
|
|
4399
|
+
const onWorldPointerMoveRef = useRef(onWorldPointerMove);
|
|
4400
|
+
onWorldPointerMoveRef.current = onWorldPointerMove;
|
|
4401
|
+
const onWorldPointerLeaveRef = useRef(onWorldPointerLeave);
|
|
4402
|
+
onWorldPointerLeaveRef.current = onWorldPointerLeave;
|
|
4403
|
+
const onPlacementPreviewChangeRef = useRef(onPlacementPreviewChange);
|
|
4404
|
+
onPlacementPreviewChangeRef.current = onPlacementPreviewChange;
|
|
4232
4405
|
const onCameraChangeRef = useRef(onCameraChange);
|
|
4233
4406
|
onCameraChangeRef.current = onCameraChange;
|
|
4234
4407
|
const onItemsChangeRef = useRef(onItemsChange);
|
|
@@ -4244,8 +4417,13 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4244
4417
|
const selectedIdsRef = useRef(selectedIds);
|
|
4245
4418
|
selectedIdsRef.current = selectedIds;
|
|
4246
4419
|
const dragStateRef = useRef({ kind: "idle" });
|
|
4247
|
-
const [placementPreview,
|
|
4248
|
-
|
|
4420
|
+
const [placementPreview, setPlacementPreviewState] = useState(null);
|
|
4421
|
+
const setRealtimePlacementPreview = useCallback(
|
|
4422
|
+
(nextPreview) => {
|
|
4423
|
+
setPlacementPreviewState(nextPreview);
|
|
4424
|
+
onPlacementPreviewChangeRef.current?.(nextPreview);
|
|
4425
|
+
},
|
|
4426
|
+
[]
|
|
4249
4427
|
);
|
|
4250
4428
|
const [eraserTrail, setEraserTrail] = useState([]);
|
|
4251
4429
|
const [laserTrail, setLaserTrail] = useState([]);
|
|
@@ -4339,6 +4517,16 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4339
4517
|
},
|
|
4340
4518
|
[]
|
|
4341
4519
|
);
|
|
4520
|
+
const notifyWorldPointerMove = useCallback(
|
|
4521
|
+
(point) => {
|
|
4522
|
+
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
4523
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4524
|
+
},
|
|
4525
|
+
[screenToWorld]
|
|
4526
|
+
);
|
|
4527
|
+
const notifyWorldPointerLeave = useCallback(() => {
|
|
4528
|
+
onWorldPointerLeaveRef.current?.();
|
|
4529
|
+
}, []);
|
|
4342
4530
|
const requestRender = useCallback(() => {
|
|
4343
4531
|
setCameraTick((n) => n + 1);
|
|
4344
4532
|
onCameraChangeRef.current?.();
|
|
@@ -4378,6 +4566,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4378
4566
|
const cam = cameraRef.current;
|
|
4379
4567
|
if (!cam) return;
|
|
4380
4568
|
const { worldX, worldY } = screenToWorld(sx, sy);
|
|
4569
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4381
4570
|
if (tool === "hand") {
|
|
4382
4571
|
dragStateRef.current = { kind: "pan" };
|
|
4383
4572
|
return;
|
|
@@ -4463,7 +4652,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4463
4652
|
kind: "marquee",
|
|
4464
4653
|
startWorld: { x: worldX, y: worldY }
|
|
4465
4654
|
};
|
|
4466
|
-
|
|
4655
|
+
setRealtimePlacementPreview({
|
|
4467
4656
|
kind: "marquee",
|
|
4468
4657
|
rect: { x: worldX, y: worldY, width: 0, height: 0 }
|
|
4469
4658
|
});
|
|
@@ -4483,7 +4672,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4483
4672
|
}
|
|
4484
4673
|
setLaserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
|
|
4485
4674
|
} else {
|
|
4486
|
-
|
|
4675
|
+
setRealtimePlacementPreview({
|
|
4487
4676
|
kind: "stroke",
|
|
4488
4677
|
tool,
|
|
4489
4678
|
points: [{ x: worldX, y: worldY }],
|
|
@@ -4516,7 +4705,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4516
4705
|
startWorld: { x: worldX, y: worldY },
|
|
4517
4706
|
startScreen: { x: sx, y: sy }
|
|
4518
4707
|
};
|
|
4519
|
-
|
|
4708
|
+
setRealtimePlacementPreview(
|
|
4520
4709
|
placementPreviewForTool(
|
|
4521
4710
|
tool,
|
|
4522
4711
|
{ x: worldX, y: worldY },
|
|
@@ -4541,7 +4730,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4541
4730
|
startWorld: { x: worldX, y: worldY },
|
|
4542
4731
|
startScreen: { x: sx, y: sy }
|
|
4543
4732
|
};
|
|
4544
|
-
|
|
4733
|
+
setRealtimePlacementPreview({
|
|
4545
4734
|
kind: "rect",
|
|
4546
4735
|
rect: { x: worldX, y: worldY, width: 0, height: 0 }
|
|
4547
4736
|
});
|
|
@@ -4570,7 +4759,13 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4570
4759
|
}
|
|
4571
4760
|
dragStateRef.current = { kind: "pan" };
|
|
4572
4761
|
},
|
|
4573
|
-
[
|
|
4762
|
+
[
|
|
4763
|
+
interactive,
|
|
4764
|
+
requestSelectToolAfterUse,
|
|
4765
|
+
screenToWorld,
|
|
4766
|
+
setRealtimePlacementPreview,
|
|
4767
|
+
updateToolCursorPoint
|
|
4768
|
+
]
|
|
4574
4769
|
);
|
|
4575
4770
|
const applyDragMoveAtScreenPoint = useCallback(
|
|
4576
4771
|
(point, pagePoint) => {
|
|
@@ -4578,6 +4773,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4578
4773
|
if (!cam) return;
|
|
4579
4774
|
updateToolCursorPoint(point);
|
|
4580
4775
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
4776
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4581
4777
|
const st = dragStateRef.current;
|
|
4582
4778
|
if (st.kind === "pan") {
|
|
4583
4779
|
const current = pagePoint ?? point;
|
|
@@ -4610,7 +4806,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4610
4806
|
}
|
|
4611
4807
|
return;
|
|
4612
4808
|
}
|
|
4613
|
-
|
|
4809
|
+
setRealtimePlacementPreview({
|
|
4614
4810
|
kind: "stroke",
|
|
4615
4811
|
tool: st.tool,
|
|
4616
4812
|
points: [...pts],
|
|
@@ -4672,7 +4868,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4672
4868
|
width: Math.abs(b.x - a.x),
|
|
4673
4869
|
height: Math.abs(b.y - a.y)
|
|
4674
4870
|
};
|
|
4675
|
-
|
|
4871
|
+
setRealtimePlacementPreview({ kind: "marquee", rect });
|
|
4676
4872
|
return;
|
|
4677
4873
|
}
|
|
4678
4874
|
if (st.kind === "erase") {
|
|
@@ -4690,7 +4886,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4690
4886
|
return;
|
|
4691
4887
|
}
|
|
4692
4888
|
if (st.kind === "place") {
|
|
4693
|
-
|
|
4889
|
+
setRealtimePlacementPreview(
|
|
4694
4890
|
placementPreviewForTool(st.tool, st.startWorld, {
|
|
4695
4891
|
x: worldX,
|
|
4696
4892
|
y: worldY
|
|
@@ -4699,14 +4895,19 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4699
4895
|
return;
|
|
4700
4896
|
}
|
|
4701
4897
|
if (st.kind === "custom-place") {
|
|
4702
|
-
|
|
4898
|
+
setRealtimePlacementPreview({
|
|
4703
4899
|
kind: "rect",
|
|
4704
4900
|
rect: rectFromCorners(st.startWorld, { x: worldX, y: worldY })
|
|
4705
4901
|
});
|
|
4706
4902
|
return;
|
|
4707
4903
|
}
|
|
4708
4904
|
},
|
|
4709
|
-
[
|
|
4905
|
+
[
|
|
4906
|
+
requestRender,
|
|
4907
|
+
screenToWorld,
|
|
4908
|
+
setRealtimePlacementPreview,
|
|
4909
|
+
updateToolCursorPoint
|
|
4910
|
+
]
|
|
4710
4911
|
);
|
|
4711
4912
|
const finishDragAtScreenPoint = useCallback(
|
|
4712
4913
|
(point) => {
|
|
@@ -4716,7 +4917,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4716
4917
|
const st = dragStateRef.current;
|
|
4717
4918
|
if (st.kind === "draw") {
|
|
4718
4919
|
dragStateRef.current = { kind: "idle" };
|
|
4719
|
-
|
|
4920
|
+
setRealtimePlacementPreview(null);
|
|
4720
4921
|
if (st.tool === "laser") {
|
|
4721
4922
|
if (laserClearTimerRef.current) {
|
|
4722
4923
|
clearTimeout(laserClearTimerRef.current);
|
|
@@ -4754,7 +4955,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4754
4955
|
}
|
|
4755
4956
|
if (st.kind === "marquee") {
|
|
4756
4957
|
dragStateRef.current = { kind: "idle" };
|
|
4757
|
-
|
|
4958
|
+
setRealtimePlacementPreview(null);
|
|
4758
4959
|
const cam = cameraRef.current;
|
|
4759
4960
|
if (!cam) return;
|
|
4760
4961
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4785,7 +4986,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4785
4986
|
}
|
|
4786
4987
|
if (st.kind === "place") {
|
|
4787
4988
|
dragStateRef.current = { kind: "idle" };
|
|
4788
|
-
|
|
4989
|
+
setRealtimePlacementPreview(null);
|
|
4789
4990
|
const change = onItemsChangeRef.current;
|
|
4790
4991
|
if (!change) return;
|
|
4791
4992
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4842,7 +5043,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4842
5043
|
}
|
|
4843
5044
|
if (st.kind === "custom-place") {
|
|
4844
5045
|
dragStateRef.current = { kind: "idle" };
|
|
4845
|
-
|
|
5046
|
+
setRealtimePlacementPreview(null);
|
|
4846
5047
|
const change = onItemsChangeRef.current;
|
|
4847
5048
|
if (!change) return;
|
|
4848
5049
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4917,7 +5118,12 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4917
5118
|
}
|
|
4918
5119
|
dragStateRef.current = { kind: "idle" };
|
|
4919
5120
|
},
|
|
4920
|
-
[
|
|
5121
|
+
[
|
|
5122
|
+
requestSelectToolAfterUse,
|
|
5123
|
+
screenToWorld,
|
|
5124
|
+
setRealtimePlacementPreview,
|
|
5125
|
+
updateToolCursorPoint
|
|
5126
|
+
]
|
|
4921
5127
|
);
|
|
4922
5128
|
const handlePointerDown = useCallback(
|
|
4923
5129
|
(event) => {
|
|
@@ -4933,9 +5139,10 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4933
5139
|
applyDragMoveAtScreenPoint(point, point);
|
|
4934
5140
|
return;
|
|
4935
5141
|
}
|
|
5142
|
+
notifyWorldPointerMove(point);
|
|
4936
5143
|
updateToolCursorPoint(point);
|
|
4937
5144
|
},
|
|
4938
|
-
[applyDragMoveAtScreenPoint, updateToolCursorPoint]
|
|
5145
|
+
[applyDragMoveAtScreenPoint, notifyWorldPointerMove, updateToolCursorPoint]
|
|
4939
5146
|
);
|
|
4940
5147
|
const handlePointerUp = useCallback(
|
|
4941
5148
|
(event) => {
|
|
@@ -4954,6 +5161,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4954
5161
|
const sy = evt.nativeEvent.locationY;
|
|
4955
5162
|
if (touches && touches.length >= 2) {
|
|
4956
5163
|
hideToolCursor();
|
|
5164
|
+
notifyWorldPointerLeave();
|
|
4957
5165
|
dragStateRef.current = { kind: "pan" };
|
|
4958
5166
|
return;
|
|
4959
5167
|
}
|
|
@@ -4969,6 +5177,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
4969
5177
|
const pageY = evt.nativeEvent.pageY;
|
|
4970
5178
|
if (touches && touches.length >= 2) {
|
|
4971
5179
|
hideToolCursor();
|
|
5180
|
+
notifyWorldPointerLeave();
|
|
4972
5181
|
const t0 = touches[0];
|
|
4973
5182
|
const t1 = touches[1];
|
|
4974
5183
|
if (t0 && t1) {
|
|
@@ -5000,8 +5209,9 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5000
5209
|
lastPinchDist.current = null;
|
|
5001
5210
|
lastPanPoint.current = null;
|
|
5002
5211
|
hideToolCursor();
|
|
5212
|
+
notifyWorldPointerLeave();
|
|
5003
5213
|
dragStateRef.current = { kind: "idle" };
|
|
5004
|
-
|
|
5214
|
+
setRealtimePlacementPreview(null);
|
|
5005
5215
|
setLaserTrail([]);
|
|
5006
5216
|
setEraserTrail([]);
|
|
5007
5217
|
setEraserPreviewIds([]);
|
|
@@ -5013,7 +5223,9 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5013
5223
|
beginDragAtScreenPoint,
|
|
5014
5224
|
finishDragAtScreenPoint,
|
|
5015
5225
|
requestRender,
|
|
5016
|
-
hideToolCursor
|
|
5226
|
+
hideToolCursor,
|
|
5227
|
+
notifyWorldPointerLeave,
|
|
5228
|
+
setRealtimePlacementPreview
|
|
5017
5229
|
]
|
|
5018
5230
|
);
|
|
5019
5231
|
useImperativeHandle(
|
|
@@ -5047,7 +5259,10 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5047
5259
|
onPointerMove: handlePointerMove,
|
|
5048
5260
|
onPointerUp: handlePointerUp,
|
|
5049
5261
|
onPointerEnter: handlePointerMove,
|
|
5050
|
-
onPointerLeave:
|
|
5262
|
+
onPointerLeave: () => {
|
|
5263
|
+
hideToolCursor();
|
|
5264
|
+
notifyWorldPointerLeave();
|
|
5265
|
+
},
|
|
5051
5266
|
...panResponder.panHandlers,
|
|
5052
5267
|
children: size.width > 0 && size.height > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5053
5268
|
/* @__PURE__ */ jsx(
|
|
@@ -5073,7 +5288,8 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5073
5288
|
eraserPreviewItems: items.filter(
|
|
5074
5289
|
(it) => eraserPreviewIds.includes(it.id)
|
|
5075
5290
|
),
|
|
5076
|
-
previewStrokeStyle: strokeStyleState
|
|
5291
|
+
previewStrokeStyle: strokeStyleState,
|
|
5292
|
+
remotePresence
|
|
5077
5293
|
}
|
|
5078
5294
|
),
|
|
5079
5295
|
interactive && showStyleInspector && activeStyleToolId ? /* @__PURE__ */ jsx(
|