canvu-react 0.4.45 → 0.4.46
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 +157 -27
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +158 -28
- package/dist/native.js.map +1 -1
- package/package.json +1 -1
package/dist/native.cjs
CHANGED
|
@@ -1869,6 +1869,63 @@ function smoothFreehandPointsToPathD(points) {
|
|
|
1869
1869
|
return d;
|
|
1870
1870
|
}
|
|
1871
1871
|
|
|
1872
|
+
// src/native/native-freehand-payload-cache.ts
|
|
1873
|
+
var MAX_NATIVE_FREEHAND_PAYLOAD_CACHE_SIZE = 800;
|
|
1874
|
+
var pathSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
1875
|
+
var payloadCache = /* @__PURE__ */ new Map();
|
|
1876
|
+
function hashNumber(hash, value) {
|
|
1877
|
+
const normalizedValue = Math.round(value * 100);
|
|
1878
|
+
return Math.imul(hash ^ normalizedValue, 16777619) >>> 0;
|
|
1879
|
+
}
|
|
1880
|
+
function getPathPointsSignature(pathPointsLocal) {
|
|
1881
|
+
const cachedSignature = pathSignatureCache.get(pathPointsLocal);
|
|
1882
|
+
if (cachedSignature) return cachedSignature;
|
|
1883
|
+
const hash = pathPointsLocal.reduce((currentHash, point) => {
|
|
1884
|
+
const withX = hashNumber(currentHash, point.x);
|
|
1885
|
+
const withY = hashNumber(withX, point.y);
|
|
1886
|
+
return hashNumber(withY, point.pressure ?? -1);
|
|
1887
|
+
}, 2166136261);
|
|
1888
|
+
const signature = `${pathPointsLocal.length}:${hash}`;
|
|
1889
|
+
pathSignatureCache.set(pathPointsLocal, signature);
|
|
1890
|
+
return signature;
|
|
1891
|
+
}
|
|
1892
|
+
function getStyleSignature(style) {
|
|
1893
|
+
return [
|
|
1894
|
+
style.stroke,
|
|
1895
|
+
style.strokeWidth,
|
|
1896
|
+
style.strokeOpacity ?? "",
|
|
1897
|
+
style.strokeDash ?? ""
|
|
1898
|
+
].join(":");
|
|
1899
|
+
}
|
|
1900
|
+
function getPayloadCacheKey(input) {
|
|
1901
|
+
return [
|
|
1902
|
+
input.itemId,
|
|
1903
|
+
input.toolKind,
|
|
1904
|
+
getStyleSignature(input.style),
|
|
1905
|
+
getPathPointsSignature(input.pathPointsLocal)
|
|
1906
|
+
].join("|");
|
|
1907
|
+
}
|
|
1908
|
+
function storePayload(key, payload) {
|
|
1909
|
+
payloadCache.set(key, payload);
|
|
1910
|
+
if (payloadCache.size > MAX_NATIVE_FREEHAND_PAYLOAD_CACHE_SIZE) {
|
|
1911
|
+
const oldestKey = payloadCache.keys().next().value;
|
|
1912
|
+
if (oldestKey !== void 0) {
|
|
1913
|
+
payloadCache.delete(oldestKey);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
return payload;
|
|
1917
|
+
}
|
|
1918
|
+
function getNativeFreehandSvgPayload(input) {
|
|
1919
|
+
const key = getPayloadCacheKey(input);
|
|
1920
|
+
if (payloadCache.has(key)) {
|
|
1921
|
+
return payloadCache.get(key) ?? null;
|
|
1922
|
+
}
|
|
1923
|
+
return storePayload(
|
|
1924
|
+
key,
|
|
1925
|
+
computeFreehandSvgPayload(input.pathPointsLocal, input.style, input.toolKind)
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1872
1929
|
// src/native/native-link-card.ts
|
|
1873
1930
|
function linkHostname(href) {
|
|
1874
1931
|
try {
|
|
@@ -2871,7 +2928,12 @@ function NativeShapeRenderer({ item }) {
|
|
|
2871
2928
|
)) });
|
|
2872
2929
|
}
|
|
2873
2930
|
if ((k === "draw" || k === "pencil" || k === "brush" || k === "marker") && item.pathPointsLocal && item.pathPointsLocal.length > 0) {
|
|
2874
|
-
const payload =
|
|
2931
|
+
const payload = getNativeFreehandSvgPayload({
|
|
2932
|
+
itemId: item.id,
|
|
2933
|
+
pathPointsLocal: item.pathPointsLocal,
|
|
2934
|
+
style,
|
|
2935
|
+
toolKind: k
|
|
2936
|
+
});
|
|
2875
2937
|
if (!payload) return null;
|
|
2876
2938
|
const color = rgba(style.stroke, style.strokeOpacity);
|
|
2877
2939
|
if (payload.kind === "circle") {
|
|
@@ -5175,6 +5237,36 @@ function hitTestNativeRemotePresence(peers, camera, point) {
|
|
|
5175
5237
|
}
|
|
5176
5238
|
return null;
|
|
5177
5239
|
}
|
|
5240
|
+
|
|
5241
|
+
// src/native/native-transient-items.ts
|
|
5242
|
+
function moveNativeTransientItems({
|
|
5243
|
+
items,
|
|
5244
|
+
snapshots,
|
|
5245
|
+
dx,
|
|
5246
|
+
dy
|
|
5247
|
+
}) {
|
|
5248
|
+
return items.map((item) => {
|
|
5249
|
+
const snapshot = snapshots[item.id];
|
|
5250
|
+
if (!snapshot) return item;
|
|
5251
|
+
return {
|
|
5252
|
+
...snapshot,
|
|
5253
|
+
x: snapshot.x + dx,
|
|
5254
|
+
y: snapshot.y + dy,
|
|
5255
|
+
bounds: {
|
|
5256
|
+
...snapshot.bounds,
|
|
5257
|
+
x: snapshot.bounds.x + dx,
|
|
5258
|
+
y: snapshot.bounds.y + dy
|
|
5259
|
+
}
|
|
5260
|
+
};
|
|
5261
|
+
});
|
|
5262
|
+
}
|
|
5263
|
+
function replaceNativeTransientItem({
|
|
5264
|
+
items,
|
|
5265
|
+
itemId,
|
|
5266
|
+
item: replacement
|
|
5267
|
+
}) {
|
|
5268
|
+
return items.map((item) => item.id === itemId ? replacement : item);
|
|
5269
|
+
}
|
|
5178
5270
|
var DEFAULT_NATIVE_LINK_TOOL_DIALOG_LABELS = {
|
|
5179
5271
|
title: "Add link",
|
|
5180
5272
|
description: "Paste the link you want to add to the board.",
|
|
@@ -5321,13 +5413,41 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5321
5413
|
customPlacementsRef.current = customPlacements;
|
|
5322
5414
|
const onSelectionChangeRef = react.useRef(onSelectionChange);
|
|
5323
5415
|
onSelectionChangeRef.current = onSelectionChange;
|
|
5324
|
-
const
|
|
5325
|
-
|
|
5416
|
+
const [transientItems, setTransientItems] = react.useState(
|
|
5417
|
+
null
|
|
5418
|
+
);
|
|
5419
|
+
const transientItemsRef = react.useRef(null);
|
|
5420
|
+
const activeItems = transientItems ?? items;
|
|
5421
|
+
const itemsRef = react.useRef(activeItems);
|
|
5422
|
+
itemsRef.current = activeItems;
|
|
5326
5423
|
const selectedIdsRef = react.useRef(selectedIds);
|
|
5327
5424
|
selectedIdsRef.current = selectedIds;
|
|
5328
5425
|
const remotePresenceRef = react.useRef(remotePresence);
|
|
5329
5426
|
remotePresenceRef.current = remotePresence;
|
|
5330
5427
|
const dragStateRef = react.useRef({ kind: "idle" });
|
|
5428
|
+
react.useEffect(() => {
|
|
5429
|
+
const committedItems = items;
|
|
5430
|
+
if (transientItemsRef.current === null && itemsRef.current === committedItems) {
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
transientItemsRef.current = null;
|
|
5434
|
+
setTransientItems(null);
|
|
5435
|
+
}, [items]);
|
|
5436
|
+
const setTransientItemsPreview = react.useCallback((nextItems) => {
|
|
5437
|
+
transientItemsRef.current = nextItems;
|
|
5438
|
+
setTransientItems(nextItems);
|
|
5439
|
+
}, []);
|
|
5440
|
+
const clearTransientItemsPreview = react.useCallback(() => {
|
|
5441
|
+
transientItemsRef.current = null;
|
|
5442
|
+
setTransientItems(null);
|
|
5443
|
+
}, []);
|
|
5444
|
+
const commitTransientItemsPreview = react.useCallback(() => {
|
|
5445
|
+
const nextItems = transientItemsRef.current;
|
|
5446
|
+
const change = onItemsChangeRef.current;
|
|
5447
|
+
if (!nextItems || !change) return false;
|
|
5448
|
+
change(nextItems);
|
|
5449
|
+
return true;
|
|
5450
|
+
}, []);
|
|
5331
5451
|
const [placementPreview, setPlacementPreviewState] = react.useState(null);
|
|
5332
5452
|
const setRealtimePlacementPreview = react.useCallback(
|
|
5333
5453
|
(nextPreview) => {
|
|
@@ -5468,8 +5588,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5468
5588
|
const hideToolCursor = react.useCallback(() => {
|
|
5469
5589
|
}, []);
|
|
5470
5590
|
const selectedItems = react.useMemo(
|
|
5471
|
-
() =>
|
|
5472
|
-
[
|
|
5591
|
+
() => activeItems.filter((item) => selectedIds.includes(item.id)),
|
|
5592
|
+
[activeItems, selectedIds]
|
|
5473
5593
|
);
|
|
5474
5594
|
const selectedStyleInspectorState = react.useMemo(() => {
|
|
5475
5595
|
const styleableItems = selectedItems.filter(
|
|
@@ -5485,10 +5605,10 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5485
5605
|
};
|
|
5486
5606
|
}, [selectedItems]);
|
|
5487
5607
|
const sceneItems = react.useMemo(() => {
|
|
5488
|
-
if (eraserPreviewIds.length === 0) return
|
|
5608
|
+
if (eraserPreviewIds.length === 0) return activeItems;
|
|
5489
5609
|
const hidden = new Set(eraserPreviewIds);
|
|
5490
|
-
return
|
|
5491
|
-
}, [
|
|
5610
|
+
return activeItems.filter((item) => !hidden.has(item.id));
|
|
5611
|
+
}, [activeItems, eraserPreviewIds]);
|
|
5492
5612
|
const showResizeHandles = interactive && selectedItems.length === 1 && !selectedItems[0]?.locked && supportsNativeResizeHandles(selectedItems[0]);
|
|
5493
5613
|
const patchSelectedItemsStrokeStyle = react.useCallback(
|
|
5494
5614
|
(patch) => {
|
|
@@ -5786,21 +5906,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5786
5906
|
const dy = worldY - st.startWorld.y;
|
|
5787
5907
|
const change = onItemsChangeRef.current;
|
|
5788
5908
|
if (!change) return;
|
|
5789
|
-
const
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
x: snap.x + dx,
|
|
5795
|
-
y: snap.y + dy,
|
|
5796
|
-
bounds: {
|
|
5797
|
-
...snap.bounds,
|
|
5798
|
-
x: snap.bounds.x + dx,
|
|
5799
|
-
y: snap.bounds.y + dy
|
|
5800
|
-
}
|
|
5801
|
-
};
|
|
5909
|
+
const nextItems = moveNativeTransientItems({
|
|
5910
|
+
items: itemsRef.current,
|
|
5911
|
+
snapshots: st.snapshots,
|
|
5912
|
+
dx,
|
|
5913
|
+
dy
|
|
5802
5914
|
});
|
|
5803
|
-
|
|
5915
|
+
setTransientItemsPreview(nextItems);
|
|
5804
5916
|
return;
|
|
5805
5917
|
}
|
|
5806
5918
|
if (st.kind === "rotate") {
|
|
@@ -5813,7 +5925,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5813
5925
|
st.startPointerAngleRad,
|
|
5814
5926
|
angle
|
|
5815
5927
|
);
|
|
5816
|
-
|
|
5928
|
+
setTransientItemsPreview(
|
|
5929
|
+
replaceNativeTransientItem({
|
|
5930
|
+
items: itemsRef.current,
|
|
5931
|
+
itemId: st.id,
|
|
5932
|
+
item: next
|
|
5933
|
+
})
|
|
5934
|
+
);
|
|
5817
5935
|
return;
|
|
5818
5936
|
}
|
|
5819
5937
|
if (st.kind === "resize") {
|
|
@@ -5823,7 +5941,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5823
5941
|
x: worldX,
|
|
5824
5942
|
y: worldY
|
|
5825
5943
|
});
|
|
5826
|
-
|
|
5944
|
+
setTransientItemsPreview(
|
|
5945
|
+
replaceNativeTransientItem({
|
|
5946
|
+
items: itemsRef.current,
|
|
5947
|
+
itemId: st.id,
|
|
5948
|
+
item: next
|
|
5949
|
+
})
|
|
5950
|
+
);
|
|
5827
5951
|
return;
|
|
5828
5952
|
}
|
|
5829
5953
|
if (st.kind === "marquee") {
|
|
@@ -5873,6 +5997,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5873
5997
|
requestRender,
|
|
5874
5998
|
screenToWorld,
|
|
5875
5999
|
setRealtimePlacementPreview,
|
|
6000
|
+
setTransientItemsPreview,
|
|
5876
6001
|
updateToolCursorPoint
|
|
5877
6002
|
]
|
|
5878
6003
|
);
|
|
@@ -5914,10 +6039,12 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5914
6039
|
}
|
|
5915
6040
|
if (st.kind === "move") {
|
|
5916
6041
|
dragStateRef.current = { kind: "idle" };
|
|
6042
|
+
commitTransientItemsPreview();
|
|
5917
6043
|
return;
|
|
5918
6044
|
}
|
|
5919
6045
|
if (st.kind === "resize" || st.kind === "rotate") {
|
|
5920
6046
|
dragStateRef.current = { kind: "idle" };
|
|
6047
|
+
commitTransientItemsPreview();
|
|
5921
6048
|
return;
|
|
5922
6049
|
}
|
|
5923
6050
|
if (st.kind === "marquee") {
|
|
@@ -6127,6 +6254,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6127
6254
|
requestSelectToolAfterUse,
|
|
6128
6255
|
screenToWorld,
|
|
6129
6256
|
setRealtimePlacementPreview,
|
|
6257
|
+
commitTransientItemsPreview,
|
|
6130
6258
|
updateToolCursorPoint
|
|
6131
6259
|
]
|
|
6132
6260
|
);
|
|
@@ -6217,6 +6345,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6217
6345
|
notifyWorldPointerLeave();
|
|
6218
6346
|
dragStateRef.current = { kind: "idle" };
|
|
6219
6347
|
setRealtimePlacementPreview(null);
|
|
6348
|
+
clearTransientItemsPreview();
|
|
6220
6349
|
setLaserTrail([]);
|
|
6221
6350
|
setEraserTrail([]);
|
|
6222
6351
|
setEraserPreviewIds([]);
|
|
@@ -6230,7 +6359,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6230
6359
|
requestRender,
|
|
6231
6360
|
hideToolCursor,
|
|
6232
6361
|
notifyWorldPointerLeave,
|
|
6233
|
-
setRealtimePlacementPreview
|
|
6362
|
+
setRealtimePlacementPreview,
|
|
6363
|
+
clearTransientItemsPreview
|
|
6234
6364
|
]
|
|
6235
6365
|
);
|
|
6236
6366
|
react.useImperativeHandle(
|
|
@@ -6300,8 +6430,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6300
6430
|
placementPreview,
|
|
6301
6431
|
laserTrail,
|
|
6302
6432
|
eraserTrail,
|
|
6303
|
-
eraserPreviewItems:
|
|
6304
|
-
(
|
|
6433
|
+
eraserPreviewItems: activeItems.filter(
|
|
6434
|
+
(item) => eraserPreviewIds.includes(item.id)
|
|
6305
6435
|
),
|
|
6306
6436
|
previewStrokeStyle: strokeStyleState,
|
|
6307
6437
|
remotePresence
|