canvu-react 0.4.33 → 0.4.35
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 +375 -24
- 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 +377 -26
- 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/chatbot.d.cts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { C as CanvasPlugin } from './types-
|
|
2
|
+
import { C as CanvasPlugin } from './types-NBYvslB-.cjs';
|
|
3
3
|
import 'react';
|
|
4
4
|
import './types-BCCvY6ie.cjs';
|
|
5
5
|
import './shape-builders-CKEMjivV.cjs';
|
|
6
6
|
import './link-item-Dncuz2d_.cjs';
|
|
7
|
+
import './types-BQUbxMgz.cjs';
|
|
7
8
|
|
|
8
9
|
type ChatbotPluginPanelProps = {
|
|
9
10
|
/**
|
package/dist/chatbot.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { C as CanvasPlugin } from './types-
|
|
2
|
+
import { C as CanvasPlugin } from './types-DeDm865m.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import './types-BCCvY6ie.js';
|
|
5
5
|
import './shape-builders-Cyh8zvDG.js';
|
|
6
6
|
import './link-item-voRU0Up9.js';
|
|
7
|
+
import './types-B82WiQQh.js';
|
|
7
8
|
|
|
8
9
|
type ChatbotPluginPanelProps = {
|
|
9
10
|
/**
|
package/dist/native.cjs
CHANGED
|
@@ -1360,6 +1360,17 @@ function computeResizeBoundsFixedAspect(bounds, handle, currentWorld, aspect) {
|
|
|
1360
1360
|
}
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
1363
|
+
// src/react/presence/peer-color.ts
|
|
1364
|
+
function defaultPresenceColorForId(id) {
|
|
1365
|
+
let h = 2166136261;
|
|
1366
|
+
for (let i = 0; i < id.length; i++) {
|
|
1367
|
+
h ^= id.charCodeAt(i);
|
|
1368
|
+
h = Math.imul(h, 16777619);
|
|
1369
|
+
}
|
|
1370
|
+
const hue = (h >>> 0) % 360;
|
|
1371
|
+
return `hsl(${hue} 72% 42%)`;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1363
1374
|
// src/scene/freehand-path.ts
|
|
1364
1375
|
function smoothFreehandPointsToPathD(points) {
|
|
1365
1376
|
const n = points.length;
|
|
@@ -1393,6 +1404,141 @@ function smoothFreehandPointsToPathD(points) {
|
|
|
1393
1404
|
d += ` Q ${pLast.x} ${pLast.y} ${pEnd.x} ${pEnd.y}`;
|
|
1394
1405
|
return d;
|
|
1395
1406
|
}
|
|
1407
|
+
var DEFAULT_NATIVE_IMAGE_CACHE_MAX_ENTRIES = 96;
|
|
1408
|
+
function disposeCachedImage(image) {
|
|
1409
|
+
try {
|
|
1410
|
+
image.dispose?.();
|
|
1411
|
+
} catch {
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
function createNativeImageCache({
|
|
1415
|
+
loadImage,
|
|
1416
|
+
maxEntries = DEFAULT_NATIVE_IMAGE_CACHE_MAX_ENTRIES
|
|
1417
|
+
}) {
|
|
1418
|
+
const safeMaxEntries = Math.max(1, Math.round(maxEntries));
|
|
1419
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1420
|
+
let clock = 0;
|
|
1421
|
+
const touchEntry = (entry) => {
|
|
1422
|
+
clock += 1;
|
|
1423
|
+
entry.lastUsed = clock;
|
|
1424
|
+
};
|
|
1425
|
+
const createEntry = () => {
|
|
1426
|
+
clock += 1;
|
|
1427
|
+
return {
|
|
1428
|
+
lastUsed: clock,
|
|
1429
|
+
retainCount: 0
|
|
1430
|
+
};
|
|
1431
|
+
};
|
|
1432
|
+
const prune = () => {
|
|
1433
|
+
const cachedEntries = [...entries.entries()].filter(
|
|
1434
|
+
(entry) => entry[1].image != null && entry[1].retainCount === 0
|
|
1435
|
+
);
|
|
1436
|
+
if (cachedEntries.length <= safeMaxEntries) return;
|
|
1437
|
+
const evictedEntries = cachedEntries.sort(
|
|
1438
|
+
(leftEntry, rightEntry) => leftEntry[1].lastUsed - rightEntry[1].lastUsed
|
|
1439
|
+
).slice(0, cachedEntries.length - safeMaxEntries);
|
|
1440
|
+
for (const [href, entry] of evictedEntries) {
|
|
1441
|
+
entries.delete(href);
|
|
1442
|
+
disposeCachedImage(entry.image);
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
const getCached = (href) => {
|
|
1446
|
+
const entry = entries.get(href);
|
|
1447
|
+
if (!entry?.image) return null;
|
|
1448
|
+
touchEntry(entry);
|
|
1449
|
+
return entry.image;
|
|
1450
|
+
};
|
|
1451
|
+
const load = async (href) => {
|
|
1452
|
+
const cachedImage = getCached(href);
|
|
1453
|
+
if (cachedImage) return cachedImage;
|
|
1454
|
+
const existingEntry = entries.get(href);
|
|
1455
|
+
if (existingEntry?.promise) return await existingEntry.promise;
|
|
1456
|
+
const entry = existingEntry ?? createEntry();
|
|
1457
|
+
const promise = loadImage(href).then((image) => {
|
|
1458
|
+
if (!image) {
|
|
1459
|
+
if (entry.retainCount === 0) entries.delete(href);
|
|
1460
|
+
return null;
|
|
1461
|
+
}
|
|
1462
|
+
entry.image = image;
|
|
1463
|
+
entry.promise = void 0;
|
|
1464
|
+
touchEntry(entry);
|
|
1465
|
+
prune();
|
|
1466
|
+
return image;
|
|
1467
|
+
}).catch((error) => {
|
|
1468
|
+
entries.delete(href);
|
|
1469
|
+
throw error;
|
|
1470
|
+
});
|
|
1471
|
+
entry.promise = promise;
|
|
1472
|
+
entries.set(href, entry);
|
|
1473
|
+
return await promise;
|
|
1474
|
+
};
|
|
1475
|
+
const retain = (href) => {
|
|
1476
|
+
const entry = entries.get(href) ?? createEntry();
|
|
1477
|
+
entry.retainCount += 1;
|
|
1478
|
+
touchEntry(entry);
|
|
1479
|
+
entries.set(href, entry);
|
|
1480
|
+
let released = false;
|
|
1481
|
+
return () => {
|
|
1482
|
+
if (released) return;
|
|
1483
|
+
released = true;
|
|
1484
|
+
entry.retainCount = Math.max(0, entry.retainCount - 1);
|
|
1485
|
+
if (!entry.image && !entry.promise && entry.retainCount === 0) {
|
|
1486
|
+
entries.delete(href);
|
|
1487
|
+
return;
|
|
1488
|
+
}
|
|
1489
|
+
prune();
|
|
1490
|
+
};
|
|
1491
|
+
};
|
|
1492
|
+
const clear = () => {
|
|
1493
|
+
for (const entry of entries.values()) {
|
|
1494
|
+
if (entry.image) disposeCachedImage(entry.image);
|
|
1495
|
+
}
|
|
1496
|
+
entries.clear();
|
|
1497
|
+
};
|
|
1498
|
+
const size = () => [...entries.values()].filter((entry) => entry.image != null).length;
|
|
1499
|
+
return { getCached, load, retain, clear, size };
|
|
1500
|
+
}
|
|
1501
|
+
async function loadSkiaImageFromHref(href) {
|
|
1502
|
+
const { Skia } = await import('@shopify/react-native-skia');
|
|
1503
|
+
const data = await Skia.Data.fromURI(href);
|
|
1504
|
+
return Skia.Image.MakeImageFromEncoded(data);
|
|
1505
|
+
}
|
|
1506
|
+
var nativeSkiaImageCache = createNativeImageCache({
|
|
1507
|
+
loadImage: loadSkiaImageFromHref
|
|
1508
|
+
});
|
|
1509
|
+
function useCachedSkiaImage(href) {
|
|
1510
|
+
const [loadedImage, setLoadedImage] = react.useState(
|
|
1511
|
+
() => href ? { href, image: nativeSkiaImageCache.getCached(href) } : null
|
|
1512
|
+
);
|
|
1513
|
+
react.useEffect(() => {
|
|
1514
|
+
if (!href) {
|
|
1515
|
+
setLoadedImage(null);
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
const releaseImage = nativeSkiaImageCache.retain(href);
|
|
1519
|
+
const cachedImage = nativeSkiaImageCache.getCached(href);
|
|
1520
|
+
if (cachedImage) {
|
|
1521
|
+
setLoadedImage({ href, image: cachedImage });
|
|
1522
|
+
return releaseImage;
|
|
1523
|
+
}
|
|
1524
|
+
let active = true;
|
|
1525
|
+
setLoadedImage({ href, image: null });
|
|
1526
|
+
void nativeSkiaImageCache.load(href).then(
|
|
1527
|
+
(loadedImage2) => {
|
|
1528
|
+
if (active) setLoadedImage({ href, image: loadedImage2 });
|
|
1529
|
+
},
|
|
1530
|
+
() => {
|
|
1531
|
+
if (active) setLoadedImage({ href, image: null });
|
|
1532
|
+
}
|
|
1533
|
+
);
|
|
1534
|
+
return () => {
|
|
1535
|
+
active = false;
|
|
1536
|
+
releaseImage();
|
|
1537
|
+
};
|
|
1538
|
+
}, [href]);
|
|
1539
|
+
if (!href || loadedImage?.href !== href) return null;
|
|
1540
|
+
return loadedImage.image;
|
|
1541
|
+
}
|
|
1396
1542
|
|
|
1397
1543
|
// src/native/skia-transform.ts
|
|
1398
1544
|
function parseNum(s) {
|
|
@@ -1657,7 +1803,7 @@ function SvgNodeItem({ node }) {
|
|
|
1657
1803
|
function SvgImageNodeItem({
|
|
1658
1804
|
node
|
|
1659
1805
|
}) {
|
|
1660
|
-
const image =
|
|
1806
|
+
const image = useCachedSkiaImage(node.href);
|
|
1661
1807
|
if (!image) return null;
|
|
1662
1808
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1663
1809
|
reactNativeSkia.Image,
|
|
@@ -2278,6 +2424,26 @@ var HANDLE_ORDER = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
|
2278
2424
|
var ERASER_PREVIEW_OPACITY = 0.3;
|
|
2279
2425
|
var OVERLAY_STROKE_PX = 1.25;
|
|
2280
2426
|
var MARQUEE_DASH_PX = 4;
|
|
2427
|
+
var REMOTE_CURSOR_SCREEN_PX = 22;
|
|
2428
|
+
var REMOTE_LABEL_SCREEN_PX = 12;
|
|
2429
|
+
function remoteStrokePaint(tool, fallback) {
|
|
2430
|
+
if (tool === "laser") {
|
|
2431
|
+
return { stroke: LASER_TINT, strokeOpacity: 0.92, widthWorld: 4 };
|
|
2432
|
+
}
|
|
2433
|
+
if (tool === "marker") {
|
|
2434
|
+
return { stroke: fallback, strokeOpacity: 0.45, widthWorld: 14 };
|
|
2435
|
+
}
|
|
2436
|
+
if (tool === "brush") {
|
|
2437
|
+
return { stroke: fallback, strokeOpacity: 0.85, widthWorld: 5 };
|
|
2438
|
+
}
|
|
2439
|
+
if (tool === "pencil") {
|
|
2440
|
+
return { stroke: fallback, strokeOpacity: 0.9, widthWorld: 2.5 };
|
|
2441
|
+
}
|
|
2442
|
+
return { stroke: fallback, strokeOpacity: 0.95, widthWorld: 3.5 };
|
|
2443
|
+
}
|
|
2444
|
+
function isRemoteFreehandTool(tool) {
|
|
2445
|
+
return tool === "draw" || tool === "marker" || tool === "pencil" || tool === "brush";
|
|
2446
|
+
}
|
|
2281
2447
|
function pointsToSmoothPathD(points) {
|
|
2282
2448
|
if (points.length < 2) return null;
|
|
2283
2449
|
const d = smoothFreehandPointsToPathD(points);
|
|
@@ -2298,7 +2464,8 @@ function NativeInteractionOverlay({
|
|
|
2298
2464
|
eraserTrail,
|
|
2299
2465
|
laserTrail,
|
|
2300
2466
|
eraserPreviewItems = [],
|
|
2301
|
-
previewStrokeStyle
|
|
2467
|
+
previewStrokeStyle,
|
|
2468
|
+
remotePresence = []
|
|
2302
2469
|
}) {
|
|
2303
2470
|
const z = camera.zoom;
|
|
2304
2471
|
const camTransform = skiaCameraTransform(z, camera.x, camera.y);
|
|
@@ -2692,6 +2859,136 @@ function NativeInteractionOverlay({
|
|
|
2692
2859
|
)
|
|
2693
2860
|
] });
|
|
2694
2861
|
}, [laserTrail, z]);
|
|
2862
|
+
const remotePresenceElements = react.useMemo(() => {
|
|
2863
|
+
if (remotePresence.length === 0) return null;
|
|
2864
|
+
const labelFont = reactNativeSkia.matchFont({ fontSize: REMOTE_LABEL_SCREEN_PX / z });
|
|
2865
|
+
const cursorSize = REMOTE_CURSOR_SCREEN_PX / z;
|
|
2866
|
+
const labelOffsetX = 14 / z;
|
|
2867
|
+
const labelOffsetY = 18 / z;
|
|
2868
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: remotePresence.map((peer) => {
|
|
2869
|
+
const color = peer.color ?? defaultPresenceColorForId(peer.id);
|
|
2870
|
+
const markup = peer.markupStroke;
|
|
2871
|
+
const cursor = peer.cursor;
|
|
2872
|
+
const camera2 = peer.camera;
|
|
2873
|
+
let strokeElement = null;
|
|
2874
|
+
if (markup && markup.points.length > 0) {
|
|
2875
|
+
const fallbackPaint = remoteStrokePaint(markup.tool, color);
|
|
2876
|
+
const paint = {
|
|
2877
|
+
stroke: markup.stroke ?? fallbackPaint.stroke,
|
|
2878
|
+
strokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,
|
|
2879
|
+
widthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld
|
|
2880
|
+
};
|
|
2881
|
+
if (markup.tool === "laser") {
|
|
2882
|
+
const d = markup.points.length >= 2 ? smoothFreehandPointsToPathD([...markup.points]) : null;
|
|
2883
|
+
if (d) {
|
|
2884
|
+
strokeElement = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2885
|
+
reactNativeSkia.Path,
|
|
2886
|
+
{
|
|
2887
|
+
path: d,
|
|
2888
|
+
color: colorWithOpacity(paint.stroke, paint.strokeOpacity),
|
|
2889
|
+
style: "stroke",
|
|
2890
|
+
strokeWidth: Math.max(paint.widthWorld, OVERLAY_STROKE_PX) / z,
|
|
2891
|
+
strokeCap: "round",
|
|
2892
|
+
strokeJoin: "round",
|
|
2893
|
+
antiAlias: true
|
|
2894
|
+
}
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
if (!strokeElement && isRemoteFreehandTool(markup.tool)) {
|
|
2899
|
+
const payload = computeFreehandSvgPayload(
|
|
2900
|
+
markup.points.map((point) => ({ x: point.x, y: point.y })),
|
|
2901
|
+
{
|
|
2902
|
+
stroke: paint.stroke,
|
|
2903
|
+
strokeWidth: paint.widthWorld,
|
|
2904
|
+
strokeOpacity: paint.strokeOpacity
|
|
2905
|
+
},
|
|
2906
|
+
markup.tool,
|
|
2907
|
+
markup.points.length === 2
|
|
2908
|
+
);
|
|
2909
|
+
if (payload?.kind === "circle") {
|
|
2910
|
+
strokeElement = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2911
|
+
reactNativeSkia.Circle,
|
|
2912
|
+
{
|
|
2913
|
+
cx: payload.cx,
|
|
2914
|
+
cy: payload.cy,
|
|
2915
|
+
r: payload.r,
|
|
2916
|
+
color: colorWithOpacity(payload.fill, payload.fillOpacity),
|
|
2917
|
+
style: "fill",
|
|
2918
|
+
antiAlias: true
|
|
2919
|
+
}
|
|
2920
|
+
);
|
|
2921
|
+
}
|
|
2922
|
+
if (payload?.kind === "fillPath") {
|
|
2923
|
+
strokeElement = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2924
|
+
reactNativeSkia.Path,
|
|
2925
|
+
{
|
|
2926
|
+
path: payload.d,
|
|
2927
|
+
color: colorWithOpacity(payload.fill, payload.fillOpacity),
|
|
2928
|
+
style: "fill",
|
|
2929
|
+
fillType: "winding",
|
|
2930
|
+
antiAlias: true
|
|
2931
|
+
}
|
|
2932
|
+
);
|
|
2933
|
+
}
|
|
2934
|
+
if (payload?.kind === "strokePath") {
|
|
2935
|
+
strokeElement = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2936
|
+
reactNativeSkia.Path,
|
|
2937
|
+
{
|
|
2938
|
+
path: payload.d,
|
|
2939
|
+
color: colorWithOpacity(payload.stroke, payload.strokeOpacity),
|
|
2940
|
+
style: "stroke",
|
|
2941
|
+
strokeWidth: payload.strokeWidth,
|
|
2942
|
+
strokeCap: "round",
|
|
2943
|
+
strokeJoin: "round",
|
|
2944
|
+
antiAlias: true
|
|
2945
|
+
}
|
|
2946
|
+
);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
const cameraElement = camera2 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2951
|
+
reactNativeSkia.Rect,
|
|
2952
|
+
{
|
|
2953
|
+
x: -camera2.x / camera2.zoom,
|
|
2954
|
+
y: -camera2.y / camera2.zoom,
|
|
2955
|
+
width: camera2.viewportWidth / camera2.zoom,
|
|
2956
|
+
height: camera2.viewportHeight / camera2.zoom,
|
|
2957
|
+
color,
|
|
2958
|
+
style: "stroke",
|
|
2959
|
+
strokeWidth: overlayStrokeWorld,
|
|
2960
|
+
antiAlias: true,
|
|
2961
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.DashPathEffect, { intervals: [marqueeDashWorld, marqueeDashWorld] })
|
|
2962
|
+
}
|
|
2963
|
+
) : null;
|
|
2964
|
+
const cursorElement = cursor ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2965
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2966
|
+
reactNativeSkia.Path,
|
|
2967
|
+
{
|
|
2968
|
+
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`,
|
|
2969
|
+
color,
|
|
2970
|
+
style: "fill",
|
|
2971
|
+
antiAlias: true
|
|
2972
|
+
}
|
|
2973
|
+
),
|
|
2974
|
+
peer.displayName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2975
|
+
reactNativeSkia.Text,
|
|
2976
|
+
{
|
|
2977
|
+
x: cursor.x + labelOffsetX,
|
|
2978
|
+
y: cursor.y + labelOffsetY,
|
|
2979
|
+
text: peer.displayName,
|
|
2980
|
+
color,
|
|
2981
|
+
font: labelFont
|
|
2982
|
+
}
|
|
2983
|
+
) : null
|
|
2984
|
+
] }) : null;
|
|
2985
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNativeSkia.Group, { children: [
|
|
2986
|
+
cameraElement,
|
|
2987
|
+
strokeElement,
|
|
2988
|
+
cursorElement
|
|
2989
|
+
] }, peer.clientId ?? peer.id);
|
|
2990
|
+
}) });
|
|
2991
|
+
}, [remotePresence, z, overlayStrokeWorld, marqueeDashWorld]);
|
|
2695
2992
|
if (width <= 0 || height <= 0) return null;
|
|
2696
2993
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2697
2994
|
reactNativeSkia.Canvas,
|
|
@@ -2709,6 +3006,7 @@ function NativeInteractionOverlay({
|
|
|
2709
3006
|
laserTrailElements,
|
|
2710
3007
|
eraserTrailElements,
|
|
2711
3008
|
eraserPreviewElements,
|
|
3009
|
+
remotePresenceElements,
|
|
2712
3010
|
selectionElements
|
|
2713
3011
|
] })
|
|
2714
3012
|
}
|
|
@@ -4211,6 +4509,7 @@ function fitCameraToWorldRect(camera, viewportW, viewportH, worldRect, padding)
|
|
|
4211
4509
|
var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
4212
4510
|
items,
|
|
4213
4511
|
selectedIds = [],
|
|
4512
|
+
remotePresence = [],
|
|
4214
4513
|
toolId = "hand",
|
|
4215
4514
|
toolLocked = false,
|
|
4216
4515
|
interactive = false,
|
|
@@ -4218,6 +4517,9 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4218
4517
|
onItemsChange,
|
|
4219
4518
|
onToolChangeRequest,
|
|
4220
4519
|
onWorldPointerDown,
|
|
4520
|
+
onWorldPointerMove,
|
|
4521
|
+
onWorldPointerLeave,
|
|
4522
|
+
onPlacementPreviewChange,
|
|
4221
4523
|
onCameraChange,
|
|
4222
4524
|
customPlacement,
|
|
4223
4525
|
customPlacements = [],
|
|
@@ -4235,6 +4537,12 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4235
4537
|
onToolChangeRequestRef.current = onToolChangeRequest;
|
|
4236
4538
|
const onWorldPointerDownRef = react.useRef(onWorldPointerDown);
|
|
4237
4539
|
onWorldPointerDownRef.current = onWorldPointerDown;
|
|
4540
|
+
const onWorldPointerMoveRef = react.useRef(onWorldPointerMove);
|
|
4541
|
+
onWorldPointerMoveRef.current = onWorldPointerMove;
|
|
4542
|
+
const onWorldPointerLeaveRef = react.useRef(onWorldPointerLeave);
|
|
4543
|
+
onWorldPointerLeaveRef.current = onWorldPointerLeave;
|
|
4544
|
+
const onPlacementPreviewChangeRef = react.useRef(onPlacementPreviewChange);
|
|
4545
|
+
onPlacementPreviewChangeRef.current = onPlacementPreviewChange;
|
|
4238
4546
|
const onCameraChangeRef = react.useRef(onCameraChange);
|
|
4239
4547
|
onCameraChangeRef.current = onCameraChange;
|
|
4240
4548
|
const onItemsChangeRef = react.useRef(onItemsChange);
|
|
@@ -4250,8 +4558,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4250
4558
|
const selectedIdsRef = react.useRef(selectedIds);
|
|
4251
4559
|
selectedIdsRef.current = selectedIds;
|
|
4252
4560
|
const dragStateRef = react.useRef({ kind: "idle" });
|
|
4253
|
-
const [placementPreview,
|
|
4254
|
-
|
|
4561
|
+
const [placementPreview, setPlacementPreviewState] = react.useState(null);
|
|
4562
|
+
const setRealtimePlacementPreview = react.useCallback(
|
|
4563
|
+
(nextPreview) => {
|
|
4564
|
+
setPlacementPreviewState(nextPreview);
|
|
4565
|
+
onPlacementPreviewChangeRef.current?.(nextPreview);
|
|
4566
|
+
},
|
|
4567
|
+
[]
|
|
4255
4568
|
);
|
|
4256
4569
|
const [eraserTrail, setEraserTrail] = react.useState([]);
|
|
4257
4570
|
const [laserTrail, setLaserTrail] = react.useState([]);
|
|
@@ -4345,6 +4658,16 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4345
4658
|
},
|
|
4346
4659
|
[]
|
|
4347
4660
|
);
|
|
4661
|
+
const notifyWorldPointerMove = react.useCallback(
|
|
4662
|
+
(point) => {
|
|
4663
|
+
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
4664
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4665
|
+
},
|
|
4666
|
+
[screenToWorld]
|
|
4667
|
+
);
|
|
4668
|
+
const notifyWorldPointerLeave = react.useCallback(() => {
|
|
4669
|
+
onWorldPointerLeaveRef.current?.();
|
|
4670
|
+
}, []);
|
|
4348
4671
|
const requestRender = react.useCallback(() => {
|
|
4349
4672
|
setCameraTick((n) => n + 1);
|
|
4350
4673
|
onCameraChangeRef.current?.();
|
|
@@ -4384,6 +4707,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4384
4707
|
const cam = cameraRef.current;
|
|
4385
4708
|
if (!cam) return;
|
|
4386
4709
|
const { worldX, worldY } = screenToWorld(sx, sy);
|
|
4710
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4387
4711
|
if (tool === "hand") {
|
|
4388
4712
|
dragStateRef.current = { kind: "pan" };
|
|
4389
4713
|
return;
|
|
@@ -4469,7 +4793,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4469
4793
|
kind: "marquee",
|
|
4470
4794
|
startWorld: { x: worldX, y: worldY }
|
|
4471
4795
|
};
|
|
4472
|
-
|
|
4796
|
+
setRealtimePlacementPreview({
|
|
4473
4797
|
kind: "marquee",
|
|
4474
4798
|
rect: { x: worldX, y: worldY, width: 0, height: 0 }
|
|
4475
4799
|
});
|
|
@@ -4489,7 +4813,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4489
4813
|
}
|
|
4490
4814
|
setLaserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
|
|
4491
4815
|
} else {
|
|
4492
|
-
|
|
4816
|
+
setRealtimePlacementPreview({
|
|
4493
4817
|
kind: "stroke",
|
|
4494
4818
|
tool,
|
|
4495
4819
|
points: [{ x: worldX, y: worldY }],
|
|
@@ -4522,7 +4846,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4522
4846
|
startWorld: { x: worldX, y: worldY },
|
|
4523
4847
|
startScreen: { x: sx, y: sy }
|
|
4524
4848
|
};
|
|
4525
|
-
|
|
4849
|
+
setRealtimePlacementPreview(
|
|
4526
4850
|
placementPreviewForTool(
|
|
4527
4851
|
tool,
|
|
4528
4852
|
{ x: worldX, y: worldY },
|
|
@@ -4547,7 +4871,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4547
4871
|
startWorld: { x: worldX, y: worldY },
|
|
4548
4872
|
startScreen: { x: sx, y: sy }
|
|
4549
4873
|
};
|
|
4550
|
-
|
|
4874
|
+
setRealtimePlacementPreview({
|
|
4551
4875
|
kind: "rect",
|
|
4552
4876
|
rect: { x: worldX, y: worldY, width: 0, height: 0 }
|
|
4553
4877
|
});
|
|
@@ -4576,7 +4900,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4576
4900
|
}
|
|
4577
4901
|
dragStateRef.current = { kind: "pan" };
|
|
4578
4902
|
},
|
|
4579
|
-
[
|
|
4903
|
+
[
|
|
4904
|
+
interactive,
|
|
4905
|
+
requestSelectToolAfterUse,
|
|
4906
|
+
screenToWorld,
|
|
4907
|
+
setRealtimePlacementPreview,
|
|
4908
|
+
updateToolCursorPoint
|
|
4909
|
+
]
|
|
4580
4910
|
);
|
|
4581
4911
|
const applyDragMoveAtScreenPoint = react.useCallback(
|
|
4582
4912
|
(point, pagePoint) => {
|
|
@@ -4584,6 +4914,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4584
4914
|
if (!cam) return;
|
|
4585
4915
|
updateToolCursorPoint(point);
|
|
4586
4916
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
4917
|
+
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4587
4918
|
const st = dragStateRef.current;
|
|
4588
4919
|
if (st.kind === "pan") {
|
|
4589
4920
|
const current = pagePoint ?? point;
|
|
@@ -4616,7 +4947,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4616
4947
|
}
|
|
4617
4948
|
return;
|
|
4618
4949
|
}
|
|
4619
|
-
|
|
4950
|
+
setRealtimePlacementPreview({
|
|
4620
4951
|
kind: "stroke",
|
|
4621
4952
|
tool: st.tool,
|
|
4622
4953
|
points: [...pts],
|
|
@@ -4678,7 +5009,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4678
5009
|
width: Math.abs(b.x - a.x),
|
|
4679
5010
|
height: Math.abs(b.y - a.y)
|
|
4680
5011
|
};
|
|
4681
|
-
|
|
5012
|
+
setRealtimePlacementPreview({ kind: "marquee", rect });
|
|
4682
5013
|
return;
|
|
4683
5014
|
}
|
|
4684
5015
|
if (st.kind === "erase") {
|
|
@@ -4696,7 +5027,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4696
5027
|
return;
|
|
4697
5028
|
}
|
|
4698
5029
|
if (st.kind === "place") {
|
|
4699
|
-
|
|
5030
|
+
setRealtimePlacementPreview(
|
|
4700
5031
|
placementPreviewForTool(st.tool, st.startWorld, {
|
|
4701
5032
|
x: worldX,
|
|
4702
5033
|
y: worldY
|
|
@@ -4705,14 +5036,19 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4705
5036
|
return;
|
|
4706
5037
|
}
|
|
4707
5038
|
if (st.kind === "custom-place") {
|
|
4708
|
-
|
|
5039
|
+
setRealtimePlacementPreview({
|
|
4709
5040
|
kind: "rect",
|
|
4710
5041
|
rect: rectFromCorners(st.startWorld, { x: worldX, y: worldY })
|
|
4711
5042
|
});
|
|
4712
5043
|
return;
|
|
4713
5044
|
}
|
|
4714
5045
|
},
|
|
4715
|
-
[
|
|
5046
|
+
[
|
|
5047
|
+
requestRender,
|
|
5048
|
+
screenToWorld,
|
|
5049
|
+
setRealtimePlacementPreview,
|
|
5050
|
+
updateToolCursorPoint
|
|
5051
|
+
]
|
|
4716
5052
|
);
|
|
4717
5053
|
const finishDragAtScreenPoint = react.useCallback(
|
|
4718
5054
|
(point) => {
|
|
@@ -4722,7 +5058,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4722
5058
|
const st = dragStateRef.current;
|
|
4723
5059
|
if (st.kind === "draw") {
|
|
4724
5060
|
dragStateRef.current = { kind: "idle" };
|
|
4725
|
-
|
|
5061
|
+
setRealtimePlacementPreview(null);
|
|
4726
5062
|
if (st.tool === "laser") {
|
|
4727
5063
|
if (laserClearTimerRef.current) {
|
|
4728
5064
|
clearTimeout(laserClearTimerRef.current);
|
|
@@ -4760,7 +5096,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4760
5096
|
}
|
|
4761
5097
|
if (st.kind === "marquee") {
|
|
4762
5098
|
dragStateRef.current = { kind: "idle" };
|
|
4763
|
-
|
|
5099
|
+
setRealtimePlacementPreview(null);
|
|
4764
5100
|
const cam = cameraRef.current;
|
|
4765
5101
|
if (!cam) return;
|
|
4766
5102
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4791,7 +5127,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4791
5127
|
}
|
|
4792
5128
|
if (st.kind === "place") {
|
|
4793
5129
|
dragStateRef.current = { kind: "idle" };
|
|
4794
|
-
|
|
5130
|
+
setRealtimePlacementPreview(null);
|
|
4795
5131
|
const change = onItemsChangeRef.current;
|
|
4796
5132
|
if (!change) return;
|
|
4797
5133
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4848,7 +5184,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4848
5184
|
}
|
|
4849
5185
|
if (st.kind === "custom-place") {
|
|
4850
5186
|
dragStateRef.current = { kind: "idle" };
|
|
4851
|
-
|
|
5187
|
+
setRealtimePlacementPreview(null);
|
|
4852
5188
|
const change = onItemsChangeRef.current;
|
|
4853
5189
|
if (!change) return;
|
|
4854
5190
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -4923,7 +5259,12 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4923
5259
|
}
|
|
4924
5260
|
dragStateRef.current = { kind: "idle" };
|
|
4925
5261
|
},
|
|
4926
|
-
[
|
|
5262
|
+
[
|
|
5263
|
+
requestSelectToolAfterUse,
|
|
5264
|
+
screenToWorld,
|
|
5265
|
+
setRealtimePlacementPreview,
|
|
5266
|
+
updateToolCursorPoint
|
|
5267
|
+
]
|
|
4927
5268
|
);
|
|
4928
5269
|
const handlePointerDown = react.useCallback(
|
|
4929
5270
|
(event) => {
|
|
@@ -4939,9 +5280,10 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4939
5280
|
applyDragMoveAtScreenPoint(point, point);
|
|
4940
5281
|
return;
|
|
4941
5282
|
}
|
|
5283
|
+
notifyWorldPointerMove(point);
|
|
4942
5284
|
updateToolCursorPoint(point);
|
|
4943
5285
|
},
|
|
4944
|
-
[applyDragMoveAtScreenPoint, updateToolCursorPoint]
|
|
5286
|
+
[applyDragMoveAtScreenPoint, notifyWorldPointerMove, updateToolCursorPoint]
|
|
4945
5287
|
);
|
|
4946
5288
|
const handlePointerUp = react.useCallback(
|
|
4947
5289
|
(event) => {
|
|
@@ -4960,6 +5302,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4960
5302
|
const sy = evt.nativeEvent.locationY;
|
|
4961
5303
|
if (touches && touches.length >= 2) {
|
|
4962
5304
|
hideToolCursor();
|
|
5305
|
+
notifyWorldPointerLeave();
|
|
4963
5306
|
dragStateRef.current = { kind: "pan" };
|
|
4964
5307
|
return;
|
|
4965
5308
|
}
|
|
@@ -4975,6 +5318,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4975
5318
|
const pageY = evt.nativeEvent.pageY;
|
|
4976
5319
|
if (touches && touches.length >= 2) {
|
|
4977
5320
|
hideToolCursor();
|
|
5321
|
+
notifyWorldPointerLeave();
|
|
4978
5322
|
const t0 = touches[0];
|
|
4979
5323
|
const t1 = touches[1];
|
|
4980
5324
|
if (t0 && t1) {
|
|
@@ -5006,8 +5350,9 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5006
5350
|
lastPinchDist.current = null;
|
|
5007
5351
|
lastPanPoint.current = null;
|
|
5008
5352
|
hideToolCursor();
|
|
5353
|
+
notifyWorldPointerLeave();
|
|
5009
5354
|
dragStateRef.current = { kind: "idle" };
|
|
5010
|
-
|
|
5355
|
+
setRealtimePlacementPreview(null);
|
|
5011
5356
|
setLaserTrail([]);
|
|
5012
5357
|
setEraserTrail([]);
|
|
5013
5358
|
setEraserPreviewIds([]);
|
|
@@ -5019,7 +5364,9 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5019
5364
|
beginDragAtScreenPoint,
|
|
5020
5365
|
finishDragAtScreenPoint,
|
|
5021
5366
|
requestRender,
|
|
5022
|
-
hideToolCursor
|
|
5367
|
+
hideToolCursor,
|
|
5368
|
+
notifyWorldPointerLeave,
|
|
5369
|
+
setRealtimePlacementPreview
|
|
5023
5370
|
]
|
|
5024
5371
|
);
|
|
5025
5372
|
react.useImperativeHandle(
|
|
@@ -5053,7 +5400,10 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5053
5400
|
onPointerMove: handlePointerMove,
|
|
5054
5401
|
onPointerUp: handlePointerUp,
|
|
5055
5402
|
onPointerEnter: handlePointerMove,
|
|
5056
|
-
onPointerLeave:
|
|
5403
|
+
onPointerLeave: () => {
|
|
5404
|
+
hideToolCursor();
|
|
5405
|
+
notifyWorldPointerLeave();
|
|
5406
|
+
},
|
|
5057
5407
|
...panResponder.panHandlers,
|
|
5058
5408
|
children: size.width > 0 && size.height > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5059
5409
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5079,7 +5429,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5079
5429
|
eraserPreviewItems: items.filter(
|
|
5080
5430
|
(it) => eraserPreviewIds.includes(it.id)
|
|
5081
5431
|
),
|
|
5082
|
-
previewStrokeStyle: strokeStyleState
|
|
5432
|
+
previewStrokeStyle: strokeStyleState,
|
|
5433
|
+
remotePresence
|
|
5083
5434
|
}
|
|
5084
5435
|
),
|
|
5085
5436
|
interactive && showStyleInspector && activeStyleToolId ? /* @__PURE__ */ jsxRuntime.jsx(
|