canvu-react 0.4.45 → 0.4.47
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 +214 -71
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +215 -72
- 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") {
|
|
@@ -2970,6 +3032,35 @@ function resolveNativeStrokePreviewStyle(tool, previewStrokeStyle) {
|
|
|
2970
3032
|
};
|
|
2971
3033
|
}
|
|
2972
3034
|
|
|
3035
|
+
// src/native/native-stroke-preview.ts
|
|
3036
|
+
var NATIVE_STROKE_PREVIEW_MAX_POINTS = 160;
|
|
3037
|
+
function sampleNativeStrokePreviewPoints(points, maxPoints = NATIVE_STROKE_PREVIEW_MAX_POINTS) {
|
|
3038
|
+
if (points.length <= maxPoints) return points.map((point) => ({ ...point }));
|
|
3039
|
+
if (maxPoints <= 1) {
|
|
3040
|
+
const last2 = points[points.length - 1];
|
|
3041
|
+
return last2 ? [{ ...last2 }] : [];
|
|
3042
|
+
}
|
|
3043
|
+
const lastIndex = points.length - 1;
|
|
3044
|
+
const last = points[lastIndex];
|
|
3045
|
+
if (!last) return [];
|
|
3046
|
+
const step = lastIndex / (maxPoints - 1);
|
|
3047
|
+
return Array.from({ length: maxPoints }, (_, index) => {
|
|
3048
|
+
const point = points[Math.round(index * step)] ?? last;
|
|
3049
|
+
return { x: point.x, y: point.y };
|
|
3050
|
+
});
|
|
3051
|
+
}
|
|
3052
|
+
function buildNativeStrokePreviewPath(points) {
|
|
3053
|
+
if (points.length < 2) return null;
|
|
3054
|
+
const d = smoothFreehandPointsToPathD(points);
|
|
3055
|
+
return d || null;
|
|
3056
|
+
}
|
|
3057
|
+
function nativeStrokePreviewDashArray(style, tool) {
|
|
3058
|
+
if (style.strokeDash !== "dashed" || tool !== "draw") return void 0;
|
|
3059
|
+
const dash = Math.max(style.strokeWidth * 1.8, 4);
|
|
3060
|
+
const gap = Math.max(style.strokeWidth * 1.4, 3);
|
|
3061
|
+
return `${dash} ${gap}`;
|
|
3062
|
+
}
|
|
3063
|
+
|
|
2973
3064
|
// src/native/native-vector-interactions.ts
|
|
2974
3065
|
var NATIVE_SELECTION_HANDLE_HIT_RADIUS_PX = 24;
|
|
2975
3066
|
function nativeItemPlacementBounds(item) {
|
|
@@ -3341,58 +3432,42 @@ function NativeInteractionOverlay({
|
|
|
3341
3432
|
p.tool,
|
|
3342
3433
|
p.style ?? previewStrokeStyle
|
|
3343
3434
|
);
|
|
3344
|
-
const
|
|
3345
|
-
|
|
3346
|
-
style
|
|
3347
|
-
isLaser ? "draw" : p.tool,
|
|
3348
|
-
p.points.length === 2
|
|
3435
|
+
const strokeColor = colorWithOpacity(
|
|
3436
|
+
style.stroke,
|
|
3437
|
+
isLaser ? 0.85 : style.strokeOpacity
|
|
3349
3438
|
);
|
|
3350
|
-
if (
|
|
3351
|
-
|
|
3439
|
+
if (p.points.length === 1) {
|
|
3440
|
+
const point = p.points[0];
|
|
3441
|
+
if (!point) return null;
|
|
3352
3442
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3353
3443
|
reactNativeSkia.Circle,
|
|
3354
3444
|
{
|
|
3355
|
-
cx:
|
|
3356
|
-
cy:
|
|
3357
|
-
r:
|
|
3358
|
-
color:
|
|
3445
|
+
cx: point.x,
|
|
3446
|
+
cy: point.y,
|
|
3447
|
+
r: Math.max(0.5, style.strokeWidth / 2),
|
|
3448
|
+
color: strokeColor,
|
|
3359
3449
|
style: "fill",
|
|
3360
3450
|
antiAlias: true
|
|
3361
3451
|
}
|
|
3362
3452
|
);
|
|
3363
3453
|
}
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
path: payload.d,
|
|
3382
|
-
color: colorWithOpacity(
|
|
3383
|
-
payload.stroke,
|
|
3384
|
-
isLaser ? 0.85 : payload.strokeOpacity
|
|
3385
|
-
),
|
|
3386
|
-
style: "stroke",
|
|
3387
|
-
strokeWidth: payload.strokeWidth,
|
|
3388
|
-
strokeCap: "round",
|
|
3389
|
-
strokeJoin: "round",
|
|
3390
|
-
antiAlias: true,
|
|
3391
|
-
children: intervals ? /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.DashPathEffect, { intervals }) : null
|
|
3392
|
-
}
|
|
3393
|
-
);
|
|
3394
|
-
}
|
|
3395
|
-
return null;
|
|
3454
|
+
const path = buildNativeStrokePreviewPath(p.points);
|
|
3455
|
+
if (!path) return null;
|
|
3456
|
+
const strokeDasharray = nativeStrokePreviewDashArray(style, p.tool);
|
|
3457
|
+
const intervals = dashIntervalsFromStrokeDasharray3(strokeDasharray);
|
|
3458
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3459
|
+
reactNativeSkia.Path,
|
|
3460
|
+
{
|
|
3461
|
+
path,
|
|
3462
|
+
color: strokeColor,
|
|
3463
|
+
style: "stroke",
|
|
3464
|
+
strokeWidth: style.strokeWidth,
|
|
3465
|
+
strokeCap: "round",
|
|
3466
|
+
strokeJoin: "round",
|
|
3467
|
+
antiAlias: true,
|
|
3468
|
+
children: intervals ? /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.DashPathEffect, { intervals }) : null
|
|
3469
|
+
}
|
|
3470
|
+
);
|
|
3396
3471
|
}
|
|
3397
3472
|
return null;
|
|
3398
3473
|
}, [placementPreview, previewStrokeStyle, overlayStrokeWorld, marqueeDashWorld]);
|
|
@@ -5175,6 +5250,36 @@ function hitTestNativeRemotePresence(peers, camera, point) {
|
|
|
5175
5250
|
}
|
|
5176
5251
|
return null;
|
|
5177
5252
|
}
|
|
5253
|
+
|
|
5254
|
+
// src/native/native-transient-items.ts
|
|
5255
|
+
function moveNativeTransientItems({
|
|
5256
|
+
items,
|
|
5257
|
+
snapshots,
|
|
5258
|
+
dx,
|
|
5259
|
+
dy
|
|
5260
|
+
}) {
|
|
5261
|
+
return items.map((item) => {
|
|
5262
|
+
const snapshot = snapshots[item.id];
|
|
5263
|
+
if (!snapshot) return item;
|
|
5264
|
+
return {
|
|
5265
|
+
...snapshot,
|
|
5266
|
+
x: snapshot.x + dx,
|
|
5267
|
+
y: snapshot.y + dy,
|
|
5268
|
+
bounds: {
|
|
5269
|
+
...snapshot.bounds,
|
|
5270
|
+
x: snapshot.bounds.x + dx,
|
|
5271
|
+
y: snapshot.bounds.y + dy
|
|
5272
|
+
}
|
|
5273
|
+
};
|
|
5274
|
+
});
|
|
5275
|
+
}
|
|
5276
|
+
function replaceNativeTransientItem({
|
|
5277
|
+
items,
|
|
5278
|
+
itemId,
|
|
5279
|
+
item: replacement
|
|
5280
|
+
}) {
|
|
5281
|
+
return items.map((item) => item.id === itemId ? replacement : item);
|
|
5282
|
+
}
|
|
5178
5283
|
var DEFAULT_NATIVE_LINK_TOOL_DIALOG_LABELS = {
|
|
5179
5284
|
title: "Add link",
|
|
5180
5285
|
description: "Paste the link you want to add to the board.",
|
|
@@ -5321,13 +5426,41 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5321
5426
|
customPlacementsRef.current = customPlacements;
|
|
5322
5427
|
const onSelectionChangeRef = react.useRef(onSelectionChange);
|
|
5323
5428
|
onSelectionChangeRef.current = onSelectionChange;
|
|
5324
|
-
const
|
|
5325
|
-
|
|
5429
|
+
const [transientItems, setTransientItems] = react.useState(
|
|
5430
|
+
null
|
|
5431
|
+
);
|
|
5432
|
+
const transientItemsRef = react.useRef(null);
|
|
5433
|
+
const activeItems = transientItems ?? items;
|
|
5434
|
+
const itemsRef = react.useRef(activeItems);
|
|
5435
|
+
itemsRef.current = activeItems;
|
|
5326
5436
|
const selectedIdsRef = react.useRef(selectedIds);
|
|
5327
5437
|
selectedIdsRef.current = selectedIds;
|
|
5328
5438
|
const remotePresenceRef = react.useRef(remotePresence);
|
|
5329
5439
|
remotePresenceRef.current = remotePresence;
|
|
5330
5440
|
const dragStateRef = react.useRef({ kind: "idle" });
|
|
5441
|
+
react.useEffect(() => {
|
|
5442
|
+
const committedItems = items;
|
|
5443
|
+
if (transientItemsRef.current === null && itemsRef.current === committedItems) {
|
|
5444
|
+
return;
|
|
5445
|
+
}
|
|
5446
|
+
transientItemsRef.current = null;
|
|
5447
|
+
setTransientItems(null);
|
|
5448
|
+
}, [items]);
|
|
5449
|
+
const setTransientItemsPreview = react.useCallback((nextItems) => {
|
|
5450
|
+
transientItemsRef.current = nextItems;
|
|
5451
|
+
setTransientItems(nextItems);
|
|
5452
|
+
}, []);
|
|
5453
|
+
const clearTransientItemsPreview = react.useCallback(() => {
|
|
5454
|
+
transientItemsRef.current = null;
|
|
5455
|
+
setTransientItems(null);
|
|
5456
|
+
}, []);
|
|
5457
|
+
const commitTransientItemsPreview = react.useCallback(() => {
|
|
5458
|
+
const nextItems = transientItemsRef.current;
|
|
5459
|
+
const change = onItemsChangeRef.current;
|
|
5460
|
+
if (!nextItems || !change) return false;
|
|
5461
|
+
change(nextItems);
|
|
5462
|
+
return true;
|
|
5463
|
+
}, []);
|
|
5331
5464
|
const [placementPreview, setPlacementPreviewState] = react.useState(null);
|
|
5332
5465
|
const setRealtimePlacementPreview = react.useCallback(
|
|
5333
5466
|
(nextPreview) => {
|
|
@@ -5468,8 +5601,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5468
5601
|
const hideToolCursor = react.useCallback(() => {
|
|
5469
5602
|
}, []);
|
|
5470
5603
|
const selectedItems = react.useMemo(
|
|
5471
|
-
() =>
|
|
5472
|
-
[
|
|
5604
|
+
() => activeItems.filter((item) => selectedIds.includes(item.id)),
|
|
5605
|
+
[activeItems, selectedIds]
|
|
5473
5606
|
);
|
|
5474
5607
|
const selectedStyleInspectorState = react.useMemo(() => {
|
|
5475
5608
|
const styleableItems = selectedItems.filter(
|
|
@@ -5485,10 +5618,10 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5485
5618
|
};
|
|
5486
5619
|
}, [selectedItems]);
|
|
5487
5620
|
const sceneItems = react.useMemo(() => {
|
|
5488
|
-
if (eraserPreviewIds.length === 0) return
|
|
5621
|
+
if (eraserPreviewIds.length === 0) return activeItems;
|
|
5489
5622
|
const hidden = new Set(eraserPreviewIds);
|
|
5490
|
-
return
|
|
5491
|
-
}, [
|
|
5623
|
+
return activeItems.filter((item) => !hidden.has(item.id));
|
|
5624
|
+
}, [activeItems, eraserPreviewIds]);
|
|
5492
5625
|
const showResizeHandles = interactive && selectedItems.length === 1 && !selectedItems[0]?.locked && supportsNativeResizeHandles(selectedItems[0]);
|
|
5493
5626
|
const patchSelectedItemsStrokeStyle = react.useCallback(
|
|
5494
5627
|
(patch) => {
|
|
@@ -5776,7 +5909,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5776
5909
|
setRealtimePlacementPreview({
|
|
5777
5910
|
kind: "stroke",
|
|
5778
5911
|
tool: st.tool,
|
|
5779
|
-
points:
|
|
5912
|
+
points: sampleNativeStrokePreviewPoints(pts),
|
|
5780
5913
|
style: { ...strokeStyleRef.current }
|
|
5781
5914
|
});
|
|
5782
5915
|
return;
|
|
@@ -5786,21 +5919,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5786
5919
|
const dy = worldY - st.startWorld.y;
|
|
5787
5920
|
const change = onItemsChangeRef.current;
|
|
5788
5921
|
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
|
-
};
|
|
5922
|
+
const nextItems = moveNativeTransientItems({
|
|
5923
|
+
items: itemsRef.current,
|
|
5924
|
+
snapshots: st.snapshots,
|
|
5925
|
+
dx,
|
|
5926
|
+
dy
|
|
5802
5927
|
});
|
|
5803
|
-
|
|
5928
|
+
setTransientItemsPreview(nextItems);
|
|
5804
5929
|
return;
|
|
5805
5930
|
}
|
|
5806
5931
|
if (st.kind === "rotate") {
|
|
@@ -5813,7 +5938,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5813
5938
|
st.startPointerAngleRad,
|
|
5814
5939
|
angle
|
|
5815
5940
|
);
|
|
5816
|
-
|
|
5941
|
+
setTransientItemsPreview(
|
|
5942
|
+
replaceNativeTransientItem({
|
|
5943
|
+
items: itemsRef.current,
|
|
5944
|
+
itemId: st.id,
|
|
5945
|
+
item: next
|
|
5946
|
+
})
|
|
5947
|
+
);
|
|
5817
5948
|
return;
|
|
5818
5949
|
}
|
|
5819
5950
|
if (st.kind === "resize") {
|
|
@@ -5823,7 +5954,13 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5823
5954
|
x: worldX,
|
|
5824
5955
|
y: worldY
|
|
5825
5956
|
});
|
|
5826
|
-
|
|
5957
|
+
setTransientItemsPreview(
|
|
5958
|
+
replaceNativeTransientItem({
|
|
5959
|
+
items: itemsRef.current,
|
|
5960
|
+
itemId: st.id,
|
|
5961
|
+
item: next
|
|
5962
|
+
})
|
|
5963
|
+
);
|
|
5827
5964
|
return;
|
|
5828
5965
|
}
|
|
5829
5966
|
if (st.kind === "marquee") {
|
|
@@ -5873,6 +6010,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5873
6010
|
requestRender,
|
|
5874
6011
|
screenToWorld,
|
|
5875
6012
|
setRealtimePlacementPreview,
|
|
6013
|
+
setTransientItemsPreview,
|
|
5876
6014
|
updateToolCursorPoint
|
|
5877
6015
|
]
|
|
5878
6016
|
);
|
|
@@ -5914,10 +6052,12 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5914
6052
|
}
|
|
5915
6053
|
if (st.kind === "move") {
|
|
5916
6054
|
dragStateRef.current = { kind: "idle" };
|
|
6055
|
+
commitTransientItemsPreview();
|
|
5917
6056
|
return;
|
|
5918
6057
|
}
|
|
5919
6058
|
if (st.kind === "resize" || st.kind === "rotate") {
|
|
5920
6059
|
dragStateRef.current = { kind: "idle" };
|
|
6060
|
+
commitTransientItemsPreview();
|
|
5921
6061
|
return;
|
|
5922
6062
|
}
|
|
5923
6063
|
if (st.kind === "marquee") {
|
|
@@ -6127,6 +6267,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6127
6267
|
requestSelectToolAfterUse,
|
|
6128
6268
|
screenToWorld,
|
|
6129
6269
|
setRealtimePlacementPreview,
|
|
6270
|
+
commitTransientItemsPreview,
|
|
6130
6271
|
updateToolCursorPoint
|
|
6131
6272
|
]
|
|
6132
6273
|
);
|
|
@@ -6217,6 +6358,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6217
6358
|
notifyWorldPointerLeave();
|
|
6218
6359
|
dragStateRef.current = { kind: "idle" };
|
|
6219
6360
|
setRealtimePlacementPreview(null);
|
|
6361
|
+
clearTransientItemsPreview();
|
|
6220
6362
|
setLaserTrail([]);
|
|
6221
6363
|
setEraserTrail([]);
|
|
6222
6364
|
setEraserPreviewIds([]);
|
|
@@ -6230,7 +6372,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6230
6372
|
requestRender,
|
|
6231
6373
|
hideToolCursor,
|
|
6232
6374
|
notifyWorldPointerLeave,
|
|
6233
|
-
setRealtimePlacementPreview
|
|
6375
|
+
setRealtimePlacementPreview,
|
|
6376
|
+
clearTransientItemsPreview
|
|
6234
6377
|
]
|
|
6235
6378
|
);
|
|
6236
6379
|
react.useImperativeHandle(
|
|
@@ -6300,8 +6443,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
6300
6443
|
placementPreview,
|
|
6301
6444
|
laserTrail,
|
|
6302
6445
|
eraserTrail,
|
|
6303
|
-
eraserPreviewItems:
|
|
6304
|
-
(
|
|
6446
|
+
eraserPreviewItems: activeItems.filter(
|
|
6447
|
+
(item) => eraserPreviewIds.includes(item.id)
|
|
6305
6448
|
),
|
|
6306
6449
|
previewStrokeStyle: strokeStyleState,
|
|
6307
6450
|
remotePresence
|