canvu-react 0.3.23 → 0.3.25
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/index.cjs +67 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +67 -40
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +177 -76
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +177 -76
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -718,6 +718,47 @@ var init_shape_builders = __esm({
|
|
|
718
718
|
}
|
|
719
719
|
});
|
|
720
720
|
|
|
721
|
+
// src/image/canvas-encode.ts
|
|
722
|
+
var DEFAULT_FALLBACK_MIME_TYPES = ["image/png"];
|
|
723
|
+
var tryCanvasToBlob = (canvas, mimeType, quality) => new Promise((resolve) => {
|
|
724
|
+
canvas.toBlob((blob) => resolve(blob), mimeType, quality);
|
|
725
|
+
});
|
|
726
|
+
var blobFromDataUrl = async (dataUrl) => {
|
|
727
|
+
const response = await fetch(dataUrl);
|
|
728
|
+
const blob = await response.blob();
|
|
729
|
+
if (blob.size === 0) {
|
|
730
|
+
throw new Error("Failed to encode canvas to blob");
|
|
731
|
+
}
|
|
732
|
+
return blob;
|
|
733
|
+
};
|
|
734
|
+
async function encodeCanvasToBlob(canvas, options) {
|
|
735
|
+
const primaryMimeType = options?.mimeType ?? "image/png";
|
|
736
|
+
const quality = options?.quality;
|
|
737
|
+
const mimeTypes = [
|
|
738
|
+
primaryMimeType,
|
|
739
|
+
...options?.fallbackMimeTypes ?? DEFAULT_FALLBACK_MIME_TYPES
|
|
740
|
+
].filter(
|
|
741
|
+
(mimeType, index, mimeTypeList) => mimeTypeList.indexOf(mimeType) === index
|
|
742
|
+
);
|
|
743
|
+
for (const mimeType of mimeTypes) {
|
|
744
|
+
const blob = await tryCanvasToBlob(
|
|
745
|
+
canvas,
|
|
746
|
+
mimeType,
|
|
747
|
+
mimeType === primaryMimeType ? quality : void 0
|
|
748
|
+
);
|
|
749
|
+
if (blob) {
|
|
750
|
+
return blob;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
for (const mimeType of mimeTypes) {
|
|
754
|
+
const dataUrl = canvas.toDataURL(mimeType, quality);
|
|
755
|
+
if (dataUrl && dataUrl !== "data:,") {
|
|
756
|
+
return blobFromDataUrl(dataUrl);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
throw new Error("Failed to encode canvas to blob");
|
|
760
|
+
}
|
|
761
|
+
|
|
721
762
|
// src/image/indexed-db-image-store.ts
|
|
722
763
|
var DB_NAME = "canvu-image-store";
|
|
723
764
|
var DB_VERSION = 1;
|
|
@@ -836,19 +877,7 @@ function decodeImageToCanvas(blob, maxDimension) {
|
|
|
836
877
|
});
|
|
837
878
|
}
|
|
838
879
|
function canvasToBlob(canvas, mime, quality) {
|
|
839
|
-
return
|
|
840
|
-
canvas.toBlob(
|
|
841
|
-
(blob) => {
|
|
842
|
-
if (!blob) {
|
|
843
|
-
reject(new Error("Could not encode blob"));
|
|
844
|
-
return;
|
|
845
|
-
}
|
|
846
|
-
resolve(blob);
|
|
847
|
-
},
|
|
848
|
-
mime,
|
|
849
|
-
quality
|
|
850
|
-
);
|
|
851
|
-
});
|
|
880
|
+
return encodeCanvasToBlob(canvas, { mimeType: mime, quality });
|
|
852
881
|
}
|
|
853
882
|
async function loadImageToStore(file, store) {
|
|
854
883
|
const originalBlob = file;
|
|
@@ -916,21 +945,6 @@ async function renderPageToCanvas(page, scale) {
|
|
|
916
945
|
await page.render({ canvas, viewport }).promise;
|
|
917
946
|
return { canvas, width: w, height: h };
|
|
918
947
|
}
|
|
919
|
-
function canvasToBlob2(canvas, mime, quality) {
|
|
920
|
-
return new Promise((resolve, reject) => {
|
|
921
|
-
canvas.toBlob(
|
|
922
|
-
(blob) => {
|
|
923
|
-
if (!blob) {
|
|
924
|
-
reject(new Error("Could not encode blob"));
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
resolve(blob);
|
|
928
|
-
},
|
|
929
|
-
mime,
|
|
930
|
-
quality
|
|
931
|
-
);
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
948
|
function normalizePdfPageNumbers(pageNumbers, pageCount) {
|
|
935
949
|
if (!pageNumbers || pageNumbers.length === 0) {
|
|
936
950
|
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
@@ -992,7 +1006,7 @@ async function loadPdfToStore(file, store, options) {
|
|
|
992
1006
|
const page = await pdf.getPage(pageNumber);
|
|
993
1007
|
const { canvas, width, height } = await renderPageToCanvas(page, scale);
|
|
994
1008
|
const mime = "image/png";
|
|
995
|
-
const pageBlob = await
|
|
1009
|
+
const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
|
|
996
1010
|
const blobId = await store.storeOriginal(pageBlob);
|
|
997
1011
|
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
998
1012
|
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
@@ -1007,7 +1021,9 @@ async function loadPdfToStore(file, store, options) {
|
|
|
1007
1021
|
tCtx.imageSmoothingQuality = "high";
|
|
1008
1022
|
tCtx.drawImage(canvas, 0, 0, tw, th);
|
|
1009
1023
|
}
|
|
1010
|
-
const thumbBlob = await
|
|
1024
|
+
const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
|
|
1025
|
+
mimeType: mime
|
|
1026
|
+
});
|
|
1011
1027
|
return await store.storeThumbnail(thumbBlob);
|
|
1012
1028
|
})() : "";
|
|
1013
1029
|
const pageResult = {
|
|
@@ -1611,6 +1627,21 @@ function reorderManagedImages(items, orderedManagedIds) {
|
|
|
1611
1627
|
});
|
|
1612
1628
|
return restackManagedImages(next);
|
|
1613
1629
|
}
|
|
1630
|
+
var OPEN_KEYFRAME_ID = "canvu-images-menu-open-keyframe";
|
|
1631
|
+
var OPEN_KEYFRAME_CSS = `
|
|
1632
|
+
@keyframes canvu-images-menu-open {
|
|
1633
|
+
from { opacity: 0; transform: scale(0.6); }
|
|
1634
|
+
to { opacity: 1; transform: scale(1); }
|
|
1635
|
+
}
|
|
1636
|
+
`;
|
|
1637
|
+
function ensureOpenKeyframe() {
|
|
1638
|
+
if (typeof document === "undefined") return;
|
|
1639
|
+
if (document.getElementById(OPEN_KEYFRAME_ID)) return;
|
|
1640
|
+
const style = document.createElement("style");
|
|
1641
|
+
style.id = OPEN_KEYFRAME_ID;
|
|
1642
|
+
style.textContent = OPEN_KEYFRAME_CSS;
|
|
1643
|
+
document.head.appendChild(style);
|
|
1644
|
+
}
|
|
1614
1645
|
var panelStyle = {
|
|
1615
1646
|
width: "fit-content",
|
|
1616
1647
|
maxHeight: "min(85dvh, 820px)",
|
|
@@ -1621,7 +1652,9 @@ var panelStyle = {
|
|
|
1621
1652
|
boxShadow: "0 10px 40px rgba(15, 23, 42, 0.12)",
|
|
1622
1653
|
fontFamily: "system-ui, sans-serif",
|
|
1623
1654
|
fontSize: 14,
|
|
1624
|
-
color: "#0f172a"
|
|
1655
|
+
color: "#0f172a",
|
|
1656
|
+
transformOrigin: "top right",
|
|
1657
|
+
animation: "canvu-images-menu-open 180ms cubic-bezier(0.2, 0.8, 0.2, 1)"
|
|
1625
1658
|
};
|
|
1626
1659
|
var headerStyle = {
|
|
1627
1660
|
display: "flex",
|
|
@@ -1743,33 +1776,16 @@ var collapsedButtonStyle = {
|
|
|
1743
1776
|
display: "inline-flex",
|
|
1744
1777
|
alignItems: "center",
|
|
1745
1778
|
justifyContent: "center",
|
|
1746
|
-
|
|
1779
|
+
width: 44,
|
|
1747
1780
|
height: 44,
|
|
1748
|
-
|
|
1749
|
-
padding: "0 12px",
|
|
1781
|
+
padding: 0,
|
|
1750
1782
|
border: "1px solid #e2e8f0",
|
|
1751
|
-
borderRadius:
|
|
1783
|
+
borderRadius: 10,
|
|
1752
1784
|
background: "#ffffff",
|
|
1753
1785
|
color: "#0f172a",
|
|
1754
1786
|
cursor: "pointer",
|
|
1755
|
-
fontFamily: "system-ui, sans-serif",
|
|
1756
|
-
fontSize: 13,
|
|
1757
|
-
fontWeight: 600,
|
|
1758
1787
|
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.12)"
|
|
1759
1788
|
};
|
|
1760
|
-
var collapsedCountStyle = {
|
|
1761
|
-
display: "inline-flex",
|
|
1762
|
-
alignItems: "center",
|
|
1763
|
-
justifyContent: "center",
|
|
1764
|
-
minWidth: 20,
|
|
1765
|
-
height: 20,
|
|
1766
|
-
padding: "0 6px",
|
|
1767
|
-
borderRadius: 10,
|
|
1768
|
-
backgroundColor: "#0f172a",
|
|
1769
|
-
color: "#ffffff",
|
|
1770
|
-
fontSize: 11,
|
|
1771
|
-
fontWeight: 600
|
|
1772
|
-
};
|
|
1773
1789
|
var defaultLabels = {
|
|
1774
1790
|
title: "Images",
|
|
1775
1791
|
dragHandle: "Drag to reorder",
|
|
@@ -1793,12 +1809,15 @@ function ImagesMenu({
|
|
|
1793
1809
|
})
|
|
1794
1810
|
);
|
|
1795
1811
|
const [collapsed, setCollapsed] = react.useState(false);
|
|
1812
|
+
react.useEffect(() => {
|
|
1813
|
+
ensureOpenKeyframe();
|
|
1814
|
+
}, []);
|
|
1796
1815
|
if (managed.length === 0) {
|
|
1797
1816
|
return null;
|
|
1798
1817
|
}
|
|
1799
1818
|
const resolvedLabels = { ...defaultLabels, ...labels };
|
|
1800
1819
|
if (collapsed) {
|
|
1801
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1820
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1802
1821
|
"button",
|
|
1803
1822
|
{
|
|
1804
1823
|
type: "button",
|
|
@@ -1807,10 +1826,7 @@ function ImagesMenu({
|
|
|
1807
1826
|
"aria-label": resolvedLabels.expand,
|
|
1808
1827
|
title: resolvedLabels.expand,
|
|
1809
1828
|
onClick: () => setCollapsed(false),
|
|
1810
|
-
children:
|
|
1811
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Images, { size: 20 }),
|
|
1812
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: collapsedCountStyle, children: managed.length })
|
|
1813
|
-
]
|
|
1829
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Images, { size: 20 })
|
|
1814
1830
|
}
|
|
1815
1831
|
);
|
|
1816
1832
|
}
|
|
@@ -1879,11 +1895,20 @@ function ImagesMenuRow({
|
|
|
1879
1895
|
onRotate,
|
|
1880
1896
|
onDelete
|
|
1881
1897
|
}) {
|
|
1882
|
-
const {
|
|
1898
|
+
const {
|
|
1899
|
+
attributes,
|
|
1900
|
+
listeners,
|
|
1901
|
+
setNodeRef,
|
|
1902
|
+
setActivatorNodeRef,
|
|
1903
|
+
transform,
|
|
1904
|
+
transition,
|
|
1905
|
+
isDragging
|
|
1906
|
+
} = sortable.useSortable({ id: item.id });
|
|
1907
|
+
const feedbackTransition = "background-color 140ms ease, opacity 140ms ease";
|
|
1883
1908
|
const wrapperStyle = {
|
|
1884
1909
|
...rowStyle,
|
|
1885
1910
|
transform: utilities.CSS.Transform.toString(transform),
|
|
1886
|
-
transition,
|
|
1911
|
+
transition: transition ? `${transition}, ${feedbackTransition}` : feedbackTransition,
|
|
1887
1912
|
background: isDragging ? "#eef2f7" : "transparent",
|
|
1888
1913
|
opacity: isDragging ? 0.85 : 1
|
|
1889
1914
|
};
|
|
@@ -1892,6 +1917,7 @@ function ImagesMenuRow({
|
|
|
1892
1917
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1893
1918
|
"button",
|
|
1894
1919
|
{
|
|
1920
|
+
ref: setActivatorNodeRef,
|
|
1895
1921
|
type: "button",
|
|
1896
1922
|
style: handleStyle,
|
|
1897
1923
|
"aria-label": labels.dragHandle,
|
|
@@ -4786,16 +4812,23 @@ function distanceBetween(a, b) {
|
|
|
4786
4812
|
function midpoint(a, b) {
|
|
4787
4813
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
4788
4814
|
}
|
|
4789
|
-
function
|
|
4790
|
-
switch (
|
|
4815
|
+
function wheelDeltaPixels(delta, deltaMode) {
|
|
4816
|
+
switch (deltaMode) {
|
|
4791
4817
|
case WheelEvent.DOM_DELTA_LINE:
|
|
4792
|
-
return
|
|
4818
|
+
return delta * 16;
|
|
4793
4819
|
case WheelEvent.DOM_DELTA_PAGE:
|
|
4794
|
-
return
|
|
4820
|
+
return delta * 400;
|
|
4795
4821
|
default:
|
|
4796
|
-
return
|
|
4822
|
+
return delta;
|
|
4797
4823
|
}
|
|
4798
4824
|
}
|
|
4825
|
+
var TRACKPAD_MAX_DELTA = 20;
|
|
4826
|
+
var MOUSE_WHEEL_DAMPING = 0.4;
|
|
4827
|
+
function softenWheelDelta(d) {
|
|
4828
|
+
const a = Math.abs(d);
|
|
4829
|
+
if (a <= TRACKPAD_MAX_DELTA) return d;
|
|
4830
|
+
return Math.sign(d) * (TRACKPAD_MAX_DELTA + (a - TRACKPAD_MAX_DELTA) * MOUSE_WHEEL_DAMPING);
|
|
4831
|
+
}
|
|
4799
4832
|
function attachViewportInput(options) {
|
|
4800
4833
|
const {
|
|
4801
4834
|
element,
|
|
@@ -4818,8 +4851,8 @@ function attachViewportInput(options) {
|
|
|
4818
4851
|
const onWheel = (e) => {
|
|
4819
4852
|
if (e.ctrlKey || e.metaKey) {
|
|
4820
4853
|
e.preventDefault();
|
|
4821
|
-
const dy =
|
|
4822
|
-
const normDy = Math.abs(dy) <
|
|
4854
|
+
const dy = wheelDeltaPixels(e.deltaY, e.deltaMode);
|
|
4855
|
+
const normDy = Math.abs(dy) < TRACKPAD_MAX_DELTA ? dy * 12 : dy;
|
|
4823
4856
|
const factor = Math.exp(-normDy * wheelZoomSensitivity);
|
|
4824
4857
|
const rect = element.getBoundingClientRect();
|
|
4825
4858
|
camera.setZoom(camera.zoom * factor, {
|
|
@@ -4830,8 +4863,10 @@ function attachViewportInput(options) {
|
|
|
4830
4863
|
return;
|
|
4831
4864
|
}
|
|
4832
4865
|
e.preventDefault();
|
|
4833
|
-
|
|
4834
|
-
|
|
4866
|
+
const panDx = softenWheelDelta(wheelDeltaPixels(e.deltaX, e.deltaMode));
|
|
4867
|
+
const panDy = softenWheelDelta(wheelDeltaPixels(e.deltaY, e.deltaMode));
|
|
4868
|
+
camera.x -= panDx * wheelPanSensitivity / camera.zoom;
|
|
4869
|
+
camera.y -= panDy * wheelPanSensitivity / camera.zoom;
|
|
4835
4870
|
onUpdate();
|
|
4836
4871
|
};
|
|
4837
4872
|
const onPointerDown = (e) => {
|
|
@@ -7386,6 +7421,40 @@ var VectorViewport = react.forwardRef(
|
|
|
7386
7421
|
onWorldPointerLeaveRef.current = onWorldPointerLeave;
|
|
7387
7422
|
const onPlacementPreviewChangeRef = react.useRef(onPlacementPreviewChange);
|
|
7388
7423
|
onPlacementPreviewChangeRef.current = onPlacementPreviewChange;
|
|
7424
|
+
const directRemoteStrokePreviewRef = react.useRef(false);
|
|
7425
|
+
const remoteStrokePreviewFrameRef = react.useRef(null);
|
|
7426
|
+
const pendingRemoteStrokePreviewRef = react.useRef(null);
|
|
7427
|
+
const flushRemoteStrokePreview = react.useCallback(() => {
|
|
7428
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7429
|
+
const pending = pendingRemoteStrokePreviewRef.current;
|
|
7430
|
+
if (!pending) return;
|
|
7431
|
+
onPlacementPreviewChangeRef.current?.({
|
|
7432
|
+
kind: "stroke",
|
|
7433
|
+
tool: pending.tool,
|
|
7434
|
+
points: pending.points
|
|
7435
|
+
});
|
|
7436
|
+
}, []);
|
|
7437
|
+
const emitRemoteStrokePreview = react.useCallback(
|
|
7438
|
+
(tool, points) => {
|
|
7439
|
+
if (tool === "laser") return;
|
|
7440
|
+
directRemoteStrokePreviewRef.current = true;
|
|
7441
|
+
pendingRemoteStrokePreviewRef.current = { tool, points };
|
|
7442
|
+
if (remoteStrokePreviewFrameRef.current != null) return;
|
|
7443
|
+
remoteStrokePreviewFrameRef.current = requestAnimationFrame(
|
|
7444
|
+
flushRemoteStrokePreview
|
|
7445
|
+
);
|
|
7446
|
+
},
|
|
7447
|
+
[flushRemoteStrokePreview]
|
|
7448
|
+
);
|
|
7449
|
+
const emitRemoteStrokePreviewClear = react.useCallback(() => {
|
|
7450
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7451
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7452
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7453
|
+
}
|
|
7454
|
+
pendingRemoteStrokePreviewRef.current = null;
|
|
7455
|
+
directRemoteStrokePreviewRef.current = false;
|
|
7456
|
+
onPlacementPreviewChangeRef.current?.(null);
|
|
7457
|
+
}, []);
|
|
7389
7458
|
const overlayCameraTickRef = react.useRef(false);
|
|
7390
7459
|
overlayCameraTickRef.current = interactive || remotePresence != null && remotePresence.length > 0 || presenceOverlay != null;
|
|
7391
7460
|
const pruneEraserTrail = react.useCallback(
|
|
@@ -7504,6 +7573,7 @@ var VectorViewport = react.forwardRef(
|
|
|
7504
7573
|
if (itemId) {
|
|
7505
7574
|
renderSceneWithLivePenStroke(null);
|
|
7506
7575
|
}
|
|
7576
|
+
emitRemoteStrokePreviewClear();
|
|
7507
7577
|
setPlacementPreview(null);
|
|
7508
7578
|
commitCompletedStroke({
|
|
7509
7579
|
tool,
|
|
@@ -7515,6 +7585,7 @@ var VectorViewport = react.forwardRef(
|
|
|
7515
7585
|
},
|
|
7516
7586
|
[
|
|
7517
7587
|
commitCompletedStroke,
|
|
7588
|
+
emitRemoteStrokePreviewClear,
|
|
7518
7589
|
releaseInteractionPointer,
|
|
7519
7590
|
renderSceneWithLivePenStroke
|
|
7520
7591
|
]
|
|
@@ -7626,8 +7697,18 @@ var VectorViewport = react.forwardRef(
|
|
|
7626
7697
|
};
|
|
7627
7698
|
}, [onWorldPointerMove]);
|
|
7628
7699
|
react.useEffect(() => {
|
|
7700
|
+
if (directRemoteStrokePreviewRef.current && placementPreview === null) {
|
|
7701
|
+
return;
|
|
7702
|
+
}
|
|
7629
7703
|
onPlacementPreviewChangeRef.current?.(placementPreview);
|
|
7630
7704
|
}, [placementPreview]);
|
|
7705
|
+
react.useEffect(() => {
|
|
7706
|
+
return () => {
|
|
7707
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7708
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7709
|
+
}
|
|
7710
|
+
};
|
|
7711
|
+
}, []);
|
|
7631
7712
|
react.useEffect(() => {
|
|
7632
7713
|
const scene = sceneRef.current;
|
|
7633
7714
|
if (scene) {
|
|
@@ -7658,15 +7739,22 @@ var VectorViewport = react.forwardRef(
|
|
|
7658
7739
|
react.useEffect(() => {
|
|
7659
7740
|
rememberImageBlobHrefs(items, rememberedImageBlobHrefsRef.current);
|
|
7660
7741
|
}, [items]);
|
|
7661
|
-
react.
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7742
|
+
const blobRevokeTimerRef = react.useRef(null);
|
|
7743
|
+
react.useEffect(() => {
|
|
7744
|
+
if (blobRevokeTimerRef.current !== null) {
|
|
7745
|
+
clearTimeout(blobRevokeTimerRef.current);
|
|
7746
|
+
blobRevokeTimerRef.current = null;
|
|
7747
|
+
}
|
|
7748
|
+
return () => {
|
|
7749
|
+
blobRevokeTimerRef.current = setTimeout(() => {
|
|
7750
|
+
releaseRememberedBlobHrefs(
|
|
7751
|
+
rememberedImageBlobHrefsRef.current,
|
|
7752
|
+
(href) => URL.revokeObjectURL(href)
|
|
7753
|
+
);
|
|
7754
|
+
blobRevokeTimerRef.current = null;
|
|
7755
|
+
}, 100);
|
|
7756
|
+
};
|
|
7757
|
+
}, []);
|
|
7670
7758
|
const PASTE_OFFSET_WORLD = 24;
|
|
7671
7759
|
const copyIdsToInternalClipboard = react.useCallback((ids) => {
|
|
7672
7760
|
if (ids.length === 0) return;
|
|
@@ -8614,6 +8702,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8614
8702
|
setPlacementPreview(null);
|
|
8615
8703
|
} else if (directPenStroke) {
|
|
8616
8704
|
setPlacementPreview(null);
|
|
8705
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8617
8706
|
} else {
|
|
8618
8707
|
setPlacementPreview({
|
|
8619
8708
|
kind: "stroke",
|
|
@@ -8655,6 +8744,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8655
8744
|
[
|
|
8656
8745
|
applePencilNav,
|
|
8657
8746
|
captureInteractionPointer,
|
|
8747
|
+
emitRemoteStrokePreview,
|
|
8658
8748
|
finalizeStrokeDragState,
|
|
8659
8749
|
renderSceneWithLivePenStroke,
|
|
8660
8750
|
screenToWorld
|
|
@@ -8713,6 +8803,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8713
8803
|
activeInteractionPointerIdRef.current = e.pointerId;
|
|
8714
8804
|
activeInteractionPointerTargetRef.current = null;
|
|
8715
8805
|
setPlacementPreview(null);
|
|
8806
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8716
8807
|
debugApplePencilPointer("native-pointerdown", {
|
|
8717
8808
|
pointerType: e.pointerType,
|
|
8718
8809
|
pointerId: e.pointerId,
|
|
@@ -8730,6 +8821,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8730
8821
|
};
|
|
8731
8822
|
}, [
|
|
8732
8823
|
applePencilNav,
|
|
8824
|
+
emitRemoteStrokePreview,
|
|
8733
8825
|
finalizeStrokeDragState,
|
|
8734
8826
|
interactive,
|
|
8735
8827
|
renderSceneWithLivePenStroke,
|
|
@@ -8813,6 +8905,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8813
8905
|
activeInteractionPointerTargetRef.current = null;
|
|
8814
8906
|
activeInteractionTouchIdRef.current = touch.identifier;
|
|
8815
8907
|
setPlacementPreview(null);
|
|
8908
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8816
8909
|
debugApplePencilPointer("touchstart-stroke", {
|
|
8817
8910
|
touchId: touch.identifier,
|
|
8818
8911
|
touchType: touchKind(touch),
|
|
@@ -8844,6 +8937,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8844
8937
|
renderSceneWithLivePenStroke(item);
|
|
8845
8938
|
}
|
|
8846
8939
|
setPlacementPreview(null);
|
|
8940
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8847
8941
|
}
|
|
8848
8942
|
debugApplePencilPointer("touchmove-stroke", {
|
|
8849
8943
|
touchId: touch.identifier,
|
|
@@ -8906,6 +9000,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8906
9000
|
};
|
|
8907
9001
|
}, [
|
|
8908
9002
|
applePencilNav,
|
|
9003
|
+
emitRemoteStrokePreview,
|
|
8909
9004
|
finalizeStrokeDragState,
|
|
8910
9005
|
interactive,
|
|
8911
9006
|
renderSceneWithLivePenStroke,
|
|
@@ -8960,6 +9055,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8960
9055
|
renderSceneWithLivePenStroke(item);
|
|
8961
9056
|
}
|
|
8962
9057
|
setPlacementPreview(null);
|
|
9058
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8963
9059
|
return;
|
|
8964
9060
|
}
|
|
8965
9061
|
if (st.tool === "laser") {
|
|
@@ -9101,6 +9197,9 @@ var VectorViewport = react.forwardRef(
|
|
|
9101
9197
|
}
|
|
9102
9198
|
const cam = cameraRef.current;
|
|
9103
9199
|
if (!cam) {
|
|
9200
|
+
if (st.kind === "stroke") {
|
|
9201
|
+
emitRemoteStrokePreviewClear();
|
|
9202
|
+
}
|
|
9104
9203
|
if (st.kind === "erase") {
|
|
9105
9204
|
eraserPreviewIdsRef.current.clear();
|
|
9106
9205
|
setEraserPreviewIds([]);
|
|
@@ -9332,6 +9431,8 @@ var VectorViewport = react.forwardRef(
|
|
|
9332
9431
|
document.removeEventListener("pointercancel", onUp);
|
|
9333
9432
|
};
|
|
9334
9433
|
}, [
|
|
9434
|
+
emitRemoteStrokePreview,
|
|
9435
|
+
emitRemoteStrokePreviewClear,
|
|
9335
9436
|
interactive,
|
|
9336
9437
|
pruneEraserTrail,
|
|
9337
9438
|
pruneLaserTrail,
|