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.js
CHANGED
|
@@ -711,6 +711,47 @@ var init_shape_builders = __esm({
|
|
|
711
711
|
}
|
|
712
712
|
});
|
|
713
713
|
|
|
714
|
+
// src/image/canvas-encode.ts
|
|
715
|
+
var DEFAULT_FALLBACK_MIME_TYPES = ["image/png"];
|
|
716
|
+
var tryCanvasToBlob = (canvas, mimeType, quality) => new Promise((resolve) => {
|
|
717
|
+
canvas.toBlob((blob) => resolve(blob), mimeType, quality);
|
|
718
|
+
});
|
|
719
|
+
var blobFromDataUrl = async (dataUrl) => {
|
|
720
|
+
const response = await fetch(dataUrl);
|
|
721
|
+
const blob = await response.blob();
|
|
722
|
+
if (blob.size === 0) {
|
|
723
|
+
throw new Error("Failed to encode canvas to blob");
|
|
724
|
+
}
|
|
725
|
+
return blob;
|
|
726
|
+
};
|
|
727
|
+
async function encodeCanvasToBlob(canvas, options) {
|
|
728
|
+
const primaryMimeType = options?.mimeType ?? "image/png";
|
|
729
|
+
const quality = options?.quality;
|
|
730
|
+
const mimeTypes = [
|
|
731
|
+
primaryMimeType,
|
|
732
|
+
...options?.fallbackMimeTypes ?? DEFAULT_FALLBACK_MIME_TYPES
|
|
733
|
+
].filter(
|
|
734
|
+
(mimeType, index, mimeTypeList) => mimeTypeList.indexOf(mimeType) === index
|
|
735
|
+
);
|
|
736
|
+
for (const mimeType of mimeTypes) {
|
|
737
|
+
const blob = await tryCanvasToBlob(
|
|
738
|
+
canvas,
|
|
739
|
+
mimeType,
|
|
740
|
+
mimeType === primaryMimeType ? quality : void 0
|
|
741
|
+
);
|
|
742
|
+
if (blob) {
|
|
743
|
+
return blob;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
for (const mimeType of mimeTypes) {
|
|
747
|
+
const dataUrl = canvas.toDataURL(mimeType, quality);
|
|
748
|
+
if (dataUrl && dataUrl !== "data:,") {
|
|
749
|
+
return blobFromDataUrl(dataUrl);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
throw new Error("Failed to encode canvas to blob");
|
|
753
|
+
}
|
|
754
|
+
|
|
714
755
|
// src/image/indexed-db-image-store.ts
|
|
715
756
|
var DB_NAME = "canvu-image-store";
|
|
716
757
|
var DB_VERSION = 1;
|
|
@@ -829,19 +870,7 @@ function decodeImageToCanvas(blob, maxDimension) {
|
|
|
829
870
|
});
|
|
830
871
|
}
|
|
831
872
|
function canvasToBlob(canvas, mime, quality) {
|
|
832
|
-
return
|
|
833
|
-
canvas.toBlob(
|
|
834
|
-
(blob) => {
|
|
835
|
-
if (!blob) {
|
|
836
|
-
reject(new Error("Could not encode blob"));
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
resolve(blob);
|
|
840
|
-
},
|
|
841
|
-
mime,
|
|
842
|
-
quality
|
|
843
|
-
);
|
|
844
|
-
});
|
|
873
|
+
return encodeCanvasToBlob(canvas, { mimeType: mime, quality });
|
|
845
874
|
}
|
|
846
875
|
async function loadImageToStore(file, store) {
|
|
847
876
|
const originalBlob = file;
|
|
@@ -909,21 +938,6 @@ async function renderPageToCanvas(page, scale) {
|
|
|
909
938
|
await page.render({ canvas, viewport }).promise;
|
|
910
939
|
return { canvas, width: w, height: h };
|
|
911
940
|
}
|
|
912
|
-
function canvasToBlob2(canvas, mime, quality) {
|
|
913
|
-
return new Promise((resolve, reject) => {
|
|
914
|
-
canvas.toBlob(
|
|
915
|
-
(blob) => {
|
|
916
|
-
if (!blob) {
|
|
917
|
-
reject(new Error("Could not encode blob"));
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
resolve(blob);
|
|
921
|
-
},
|
|
922
|
-
mime,
|
|
923
|
-
quality
|
|
924
|
-
);
|
|
925
|
-
});
|
|
926
|
-
}
|
|
927
941
|
function normalizePdfPageNumbers(pageNumbers, pageCount) {
|
|
928
942
|
if (!pageNumbers || pageNumbers.length === 0) {
|
|
929
943
|
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
@@ -985,7 +999,7 @@ async function loadPdfToStore(file, store, options) {
|
|
|
985
999
|
const page = await pdf.getPage(pageNumber);
|
|
986
1000
|
const { canvas, width, height } = await renderPageToCanvas(page, scale);
|
|
987
1001
|
const mime = "image/png";
|
|
988
|
-
const pageBlob = await
|
|
1002
|
+
const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
|
|
989
1003
|
const blobId = await store.storeOriginal(pageBlob);
|
|
990
1004
|
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
991
1005
|
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
@@ -1000,7 +1014,9 @@ async function loadPdfToStore(file, store, options) {
|
|
|
1000
1014
|
tCtx.imageSmoothingQuality = "high";
|
|
1001
1015
|
tCtx.drawImage(canvas, 0, 0, tw, th);
|
|
1002
1016
|
}
|
|
1003
|
-
const thumbBlob = await
|
|
1017
|
+
const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
|
|
1018
|
+
mimeType: mime
|
|
1019
|
+
});
|
|
1004
1020
|
return await store.storeThumbnail(thumbBlob);
|
|
1005
1021
|
})() : "";
|
|
1006
1022
|
const pageResult = {
|
|
@@ -1604,6 +1620,21 @@ function reorderManagedImages(items, orderedManagedIds) {
|
|
|
1604
1620
|
});
|
|
1605
1621
|
return restackManagedImages(next);
|
|
1606
1622
|
}
|
|
1623
|
+
var OPEN_KEYFRAME_ID = "canvu-images-menu-open-keyframe";
|
|
1624
|
+
var OPEN_KEYFRAME_CSS = `
|
|
1625
|
+
@keyframes canvu-images-menu-open {
|
|
1626
|
+
from { opacity: 0; transform: scale(0.6); }
|
|
1627
|
+
to { opacity: 1; transform: scale(1); }
|
|
1628
|
+
}
|
|
1629
|
+
`;
|
|
1630
|
+
function ensureOpenKeyframe() {
|
|
1631
|
+
if (typeof document === "undefined") return;
|
|
1632
|
+
if (document.getElementById(OPEN_KEYFRAME_ID)) return;
|
|
1633
|
+
const style = document.createElement("style");
|
|
1634
|
+
style.id = OPEN_KEYFRAME_ID;
|
|
1635
|
+
style.textContent = OPEN_KEYFRAME_CSS;
|
|
1636
|
+
document.head.appendChild(style);
|
|
1637
|
+
}
|
|
1607
1638
|
var panelStyle = {
|
|
1608
1639
|
width: "fit-content",
|
|
1609
1640
|
maxHeight: "min(85dvh, 820px)",
|
|
@@ -1614,7 +1645,9 @@ var panelStyle = {
|
|
|
1614
1645
|
boxShadow: "0 10px 40px rgba(15, 23, 42, 0.12)",
|
|
1615
1646
|
fontFamily: "system-ui, sans-serif",
|
|
1616
1647
|
fontSize: 14,
|
|
1617
|
-
color: "#0f172a"
|
|
1648
|
+
color: "#0f172a",
|
|
1649
|
+
transformOrigin: "top right",
|
|
1650
|
+
animation: "canvu-images-menu-open 180ms cubic-bezier(0.2, 0.8, 0.2, 1)"
|
|
1618
1651
|
};
|
|
1619
1652
|
var headerStyle = {
|
|
1620
1653
|
display: "flex",
|
|
@@ -1736,33 +1769,16 @@ var collapsedButtonStyle = {
|
|
|
1736
1769
|
display: "inline-flex",
|
|
1737
1770
|
alignItems: "center",
|
|
1738
1771
|
justifyContent: "center",
|
|
1739
|
-
|
|
1772
|
+
width: 44,
|
|
1740
1773
|
height: 44,
|
|
1741
|
-
|
|
1742
|
-
padding: "0 12px",
|
|
1774
|
+
padding: 0,
|
|
1743
1775
|
border: "1px solid #e2e8f0",
|
|
1744
|
-
borderRadius:
|
|
1776
|
+
borderRadius: 10,
|
|
1745
1777
|
background: "#ffffff",
|
|
1746
1778
|
color: "#0f172a",
|
|
1747
1779
|
cursor: "pointer",
|
|
1748
|
-
fontFamily: "system-ui, sans-serif",
|
|
1749
|
-
fontSize: 13,
|
|
1750
|
-
fontWeight: 600,
|
|
1751
1780
|
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.12)"
|
|
1752
1781
|
};
|
|
1753
|
-
var collapsedCountStyle = {
|
|
1754
|
-
display: "inline-flex",
|
|
1755
|
-
alignItems: "center",
|
|
1756
|
-
justifyContent: "center",
|
|
1757
|
-
minWidth: 20,
|
|
1758
|
-
height: 20,
|
|
1759
|
-
padding: "0 6px",
|
|
1760
|
-
borderRadius: 10,
|
|
1761
|
-
backgroundColor: "#0f172a",
|
|
1762
|
-
color: "#ffffff",
|
|
1763
|
-
fontSize: 11,
|
|
1764
|
-
fontWeight: 600
|
|
1765
|
-
};
|
|
1766
1782
|
var defaultLabels = {
|
|
1767
1783
|
title: "Images",
|
|
1768
1784
|
dragHandle: "Drag to reorder",
|
|
@@ -1786,12 +1802,15 @@ function ImagesMenu({
|
|
|
1786
1802
|
})
|
|
1787
1803
|
);
|
|
1788
1804
|
const [collapsed, setCollapsed] = useState(false);
|
|
1805
|
+
useEffect(() => {
|
|
1806
|
+
ensureOpenKeyframe();
|
|
1807
|
+
}, []);
|
|
1789
1808
|
if (managed.length === 0) {
|
|
1790
1809
|
return null;
|
|
1791
1810
|
}
|
|
1792
1811
|
const resolvedLabels = { ...defaultLabels, ...labels };
|
|
1793
1812
|
if (collapsed) {
|
|
1794
|
-
return /* @__PURE__ */
|
|
1813
|
+
return /* @__PURE__ */ jsx(
|
|
1795
1814
|
"button",
|
|
1796
1815
|
{
|
|
1797
1816
|
type: "button",
|
|
@@ -1800,10 +1819,7 @@ function ImagesMenu({
|
|
|
1800
1819
|
"aria-label": resolvedLabels.expand,
|
|
1801
1820
|
title: resolvedLabels.expand,
|
|
1802
1821
|
onClick: () => setCollapsed(false),
|
|
1803
|
-
children:
|
|
1804
|
-
/* @__PURE__ */ jsx(Images, { size: 20 }),
|
|
1805
|
-
/* @__PURE__ */ jsx("span", { style: collapsedCountStyle, children: managed.length })
|
|
1806
|
-
]
|
|
1822
|
+
children: /* @__PURE__ */ jsx(Images, { size: 20 })
|
|
1807
1823
|
}
|
|
1808
1824
|
);
|
|
1809
1825
|
}
|
|
@@ -1872,11 +1888,20 @@ function ImagesMenuRow({
|
|
|
1872
1888
|
onRotate,
|
|
1873
1889
|
onDelete
|
|
1874
1890
|
}) {
|
|
1875
|
-
const {
|
|
1891
|
+
const {
|
|
1892
|
+
attributes,
|
|
1893
|
+
listeners,
|
|
1894
|
+
setNodeRef,
|
|
1895
|
+
setActivatorNodeRef,
|
|
1896
|
+
transform,
|
|
1897
|
+
transition,
|
|
1898
|
+
isDragging
|
|
1899
|
+
} = useSortable({ id: item.id });
|
|
1900
|
+
const feedbackTransition = "background-color 140ms ease, opacity 140ms ease";
|
|
1876
1901
|
const wrapperStyle = {
|
|
1877
1902
|
...rowStyle,
|
|
1878
1903
|
transform: CSS.Transform.toString(transform),
|
|
1879
|
-
transition,
|
|
1904
|
+
transition: transition ? `${transition}, ${feedbackTransition}` : feedbackTransition,
|
|
1880
1905
|
background: isDragging ? "#eef2f7" : "transparent",
|
|
1881
1906
|
opacity: isDragging ? 0.85 : 1
|
|
1882
1907
|
};
|
|
@@ -1885,6 +1910,7 @@ function ImagesMenuRow({
|
|
|
1885
1910
|
/* @__PURE__ */ jsx(
|
|
1886
1911
|
"button",
|
|
1887
1912
|
{
|
|
1913
|
+
ref: setActivatorNodeRef,
|
|
1888
1914
|
type: "button",
|
|
1889
1915
|
style: handleStyle,
|
|
1890
1916
|
"aria-label": labels.dragHandle,
|
|
@@ -4779,16 +4805,23 @@ function distanceBetween(a, b) {
|
|
|
4779
4805
|
function midpoint(a, b) {
|
|
4780
4806
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
4781
4807
|
}
|
|
4782
|
-
function
|
|
4783
|
-
switch (
|
|
4808
|
+
function wheelDeltaPixels(delta, deltaMode) {
|
|
4809
|
+
switch (deltaMode) {
|
|
4784
4810
|
case WheelEvent.DOM_DELTA_LINE:
|
|
4785
|
-
return
|
|
4811
|
+
return delta * 16;
|
|
4786
4812
|
case WheelEvent.DOM_DELTA_PAGE:
|
|
4787
|
-
return
|
|
4813
|
+
return delta * 400;
|
|
4788
4814
|
default:
|
|
4789
|
-
return
|
|
4815
|
+
return delta;
|
|
4790
4816
|
}
|
|
4791
4817
|
}
|
|
4818
|
+
var TRACKPAD_MAX_DELTA = 20;
|
|
4819
|
+
var MOUSE_WHEEL_DAMPING = 0.4;
|
|
4820
|
+
function softenWheelDelta(d) {
|
|
4821
|
+
const a = Math.abs(d);
|
|
4822
|
+
if (a <= TRACKPAD_MAX_DELTA) return d;
|
|
4823
|
+
return Math.sign(d) * (TRACKPAD_MAX_DELTA + (a - TRACKPAD_MAX_DELTA) * MOUSE_WHEEL_DAMPING);
|
|
4824
|
+
}
|
|
4792
4825
|
function attachViewportInput(options) {
|
|
4793
4826
|
const {
|
|
4794
4827
|
element,
|
|
@@ -4811,8 +4844,8 @@ function attachViewportInput(options) {
|
|
|
4811
4844
|
const onWheel = (e) => {
|
|
4812
4845
|
if (e.ctrlKey || e.metaKey) {
|
|
4813
4846
|
e.preventDefault();
|
|
4814
|
-
const dy =
|
|
4815
|
-
const normDy = Math.abs(dy) <
|
|
4847
|
+
const dy = wheelDeltaPixels(e.deltaY, e.deltaMode);
|
|
4848
|
+
const normDy = Math.abs(dy) < TRACKPAD_MAX_DELTA ? dy * 12 : dy;
|
|
4816
4849
|
const factor = Math.exp(-normDy * wheelZoomSensitivity);
|
|
4817
4850
|
const rect = element.getBoundingClientRect();
|
|
4818
4851
|
camera.setZoom(camera.zoom * factor, {
|
|
@@ -4823,8 +4856,10 @@ function attachViewportInput(options) {
|
|
|
4823
4856
|
return;
|
|
4824
4857
|
}
|
|
4825
4858
|
e.preventDefault();
|
|
4826
|
-
|
|
4827
|
-
|
|
4859
|
+
const panDx = softenWheelDelta(wheelDeltaPixels(e.deltaX, e.deltaMode));
|
|
4860
|
+
const panDy = softenWheelDelta(wheelDeltaPixels(e.deltaY, e.deltaMode));
|
|
4861
|
+
camera.x -= panDx * wheelPanSensitivity / camera.zoom;
|
|
4862
|
+
camera.y -= panDy * wheelPanSensitivity / camera.zoom;
|
|
4828
4863
|
onUpdate();
|
|
4829
4864
|
};
|
|
4830
4865
|
const onPointerDown = (e) => {
|
|
@@ -7379,6 +7414,40 @@ var VectorViewport = forwardRef(
|
|
|
7379
7414
|
onWorldPointerLeaveRef.current = onWorldPointerLeave;
|
|
7380
7415
|
const onPlacementPreviewChangeRef = useRef(onPlacementPreviewChange);
|
|
7381
7416
|
onPlacementPreviewChangeRef.current = onPlacementPreviewChange;
|
|
7417
|
+
const directRemoteStrokePreviewRef = useRef(false);
|
|
7418
|
+
const remoteStrokePreviewFrameRef = useRef(null);
|
|
7419
|
+
const pendingRemoteStrokePreviewRef = useRef(null);
|
|
7420
|
+
const flushRemoteStrokePreview = useCallback(() => {
|
|
7421
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7422
|
+
const pending = pendingRemoteStrokePreviewRef.current;
|
|
7423
|
+
if (!pending) return;
|
|
7424
|
+
onPlacementPreviewChangeRef.current?.({
|
|
7425
|
+
kind: "stroke",
|
|
7426
|
+
tool: pending.tool,
|
|
7427
|
+
points: pending.points
|
|
7428
|
+
});
|
|
7429
|
+
}, []);
|
|
7430
|
+
const emitRemoteStrokePreview = useCallback(
|
|
7431
|
+
(tool, points) => {
|
|
7432
|
+
if (tool === "laser") return;
|
|
7433
|
+
directRemoteStrokePreviewRef.current = true;
|
|
7434
|
+
pendingRemoteStrokePreviewRef.current = { tool, points };
|
|
7435
|
+
if (remoteStrokePreviewFrameRef.current != null) return;
|
|
7436
|
+
remoteStrokePreviewFrameRef.current = requestAnimationFrame(
|
|
7437
|
+
flushRemoteStrokePreview
|
|
7438
|
+
);
|
|
7439
|
+
},
|
|
7440
|
+
[flushRemoteStrokePreview]
|
|
7441
|
+
);
|
|
7442
|
+
const emitRemoteStrokePreviewClear = useCallback(() => {
|
|
7443
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7444
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7445
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7446
|
+
}
|
|
7447
|
+
pendingRemoteStrokePreviewRef.current = null;
|
|
7448
|
+
directRemoteStrokePreviewRef.current = false;
|
|
7449
|
+
onPlacementPreviewChangeRef.current?.(null);
|
|
7450
|
+
}, []);
|
|
7382
7451
|
const overlayCameraTickRef = useRef(false);
|
|
7383
7452
|
overlayCameraTickRef.current = interactive || remotePresence != null && remotePresence.length > 0 || presenceOverlay != null;
|
|
7384
7453
|
const pruneEraserTrail = useCallback(
|
|
@@ -7497,6 +7566,7 @@ var VectorViewport = forwardRef(
|
|
|
7497
7566
|
if (itemId) {
|
|
7498
7567
|
renderSceneWithLivePenStroke(null);
|
|
7499
7568
|
}
|
|
7569
|
+
emitRemoteStrokePreviewClear();
|
|
7500
7570
|
setPlacementPreview(null);
|
|
7501
7571
|
commitCompletedStroke({
|
|
7502
7572
|
tool,
|
|
@@ -7508,6 +7578,7 @@ var VectorViewport = forwardRef(
|
|
|
7508
7578
|
},
|
|
7509
7579
|
[
|
|
7510
7580
|
commitCompletedStroke,
|
|
7581
|
+
emitRemoteStrokePreviewClear,
|
|
7511
7582
|
releaseInteractionPointer,
|
|
7512
7583
|
renderSceneWithLivePenStroke
|
|
7513
7584
|
]
|
|
@@ -7619,8 +7690,18 @@ var VectorViewport = forwardRef(
|
|
|
7619
7690
|
};
|
|
7620
7691
|
}, [onWorldPointerMove]);
|
|
7621
7692
|
useEffect(() => {
|
|
7693
|
+
if (directRemoteStrokePreviewRef.current && placementPreview === null) {
|
|
7694
|
+
return;
|
|
7695
|
+
}
|
|
7622
7696
|
onPlacementPreviewChangeRef.current?.(placementPreview);
|
|
7623
7697
|
}, [placementPreview]);
|
|
7698
|
+
useEffect(() => {
|
|
7699
|
+
return () => {
|
|
7700
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7701
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7702
|
+
}
|
|
7703
|
+
};
|
|
7704
|
+
}, []);
|
|
7624
7705
|
useEffect(() => {
|
|
7625
7706
|
const scene = sceneRef.current;
|
|
7626
7707
|
if (scene) {
|
|
@@ -7651,15 +7732,22 @@ var VectorViewport = forwardRef(
|
|
|
7651
7732
|
useEffect(() => {
|
|
7652
7733
|
rememberImageBlobHrefs(items, rememberedImageBlobHrefsRef.current);
|
|
7653
7734
|
}, [items]);
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7735
|
+
const blobRevokeTimerRef = useRef(null);
|
|
7736
|
+
useEffect(() => {
|
|
7737
|
+
if (blobRevokeTimerRef.current !== null) {
|
|
7738
|
+
clearTimeout(blobRevokeTimerRef.current);
|
|
7739
|
+
blobRevokeTimerRef.current = null;
|
|
7740
|
+
}
|
|
7741
|
+
return () => {
|
|
7742
|
+
blobRevokeTimerRef.current = setTimeout(() => {
|
|
7743
|
+
releaseRememberedBlobHrefs(
|
|
7744
|
+
rememberedImageBlobHrefsRef.current,
|
|
7745
|
+
(href) => URL.revokeObjectURL(href)
|
|
7746
|
+
);
|
|
7747
|
+
blobRevokeTimerRef.current = null;
|
|
7748
|
+
}, 100);
|
|
7749
|
+
};
|
|
7750
|
+
}, []);
|
|
7663
7751
|
const PASTE_OFFSET_WORLD = 24;
|
|
7664
7752
|
const copyIdsToInternalClipboard = useCallback((ids) => {
|
|
7665
7753
|
if (ids.length === 0) return;
|
|
@@ -8607,6 +8695,7 @@ var VectorViewport = forwardRef(
|
|
|
8607
8695
|
setPlacementPreview(null);
|
|
8608
8696
|
} else if (directPenStroke) {
|
|
8609
8697
|
setPlacementPreview(null);
|
|
8698
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8610
8699
|
} else {
|
|
8611
8700
|
setPlacementPreview({
|
|
8612
8701
|
kind: "stroke",
|
|
@@ -8648,6 +8737,7 @@ var VectorViewport = forwardRef(
|
|
|
8648
8737
|
[
|
|
8649
8738
|
applePencilNav,
|
|
8650
8739
|
captureInteractionPointer,
|
|
8740
|
+
emitRemoteStrokePreview,
|
|
8651
8741
|
finalizeStrokeDragState,
|
|
8652
8742
|
renderSceneWithLivePenStroke,
|
|
8653
8743
|
screenToWorld
|
|
@@ -8706,6 +8796,7 @@ var VectorViewport = forwardRef(
|
|
|
8706
8796
|
activeInteractionPointerIdRef.current = e.pointerId;
|
|
8707
8797
|
activeInteractionPointerTargetRef.current = null;
|
|
8708
8798
|
setPlacementPreview(null);
|
|
8799
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8709
8800
|
debugApplePencilPointer("native-pointerdown", {
|
|
8710
8801
|
pointerType: e.pointerType,
|
|
8711
8802
|
pointerId: e.pointerId,
|
|
@@ -8723,6 +8814,7 @@ var VectorViewport = forwardRef(
|
|
|
8723
8814
|
};
|
|
8724
8815
|
}, [
|
|
8725
8816
|
applePencilNav,
|
|
8817
|
+
emitRemoteStrokePreview,
|
|
8726
8818
|
finalizeStrokeDragState,
|
|
8727
8819
|
interactive,
|
|
8728
8820
|
renderSceneWithLivePenStroke,
|
|
@@ -8806,6 +8898,7 @@ var VectorViewport = forwardRef(
|
|
|
8806
8898
|
activeInteractionPointerTargetRef.current = null;
|
|
8807
8899
|
activeInteractionTouchIdRef.current = touch.identifier;
|
|
8808
8900
|
setPlacementPreview(null);
|
|
8901
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8809
8902
|
debugApplePencilPointer("touchstart-stroke", {
|
|
8810
8903
|
touchId: touch.identifier,
|
|
8811
8904
|
touchType: touchKind(touch),
|
|
@@ -8837,6 +8930,7 @@ var VectorViewport = forwardRef(
|
|
|
8837
8930
|
renderSceneWithLivePenStroke(item);
|
|
8838
8931
|
}
|
|
8839
8932
|
setPlacementPreview(null);
|
|
8933
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8840
8934
|
}
|
|
8841
8935
|
debugApplePencilPointer("touchmove-stroke", {
|
|
8842
8936
|
touchId: touch.identifier,
|
|
@@ -8899,6 +8993,7 @@ var VectorViewport = forwardRef(
|
|
|
8899
8993
|
};
|
|
8900
8994
|
}, [
|
|
8901
8995
|
applePencilNav,
|
|
8996
|
+
emitRemoteStrokePreview,
|
|
8902
8997
|
finalizeStrokeDragState,
|
|
8903
8998
|
interactive,
|
|
8904
8999
|
renderSceneWithLivePenStroke,
|
|
@@ -8953,6 +9048,7 @@ var VectorViewport = forwardRef(
|
|
|
8953
9048
|
renderSceneWithLivePenStroke(item);
|
|
8954
9049
|
}
|
|
8955
9050
|
setPlacementPreview(null);
|
|
9051
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8956
9052
|
return;
|
|
8957
9053
|
}
|
|
8958
9054
|
if (st.tool === "laser") {
|
|
@@ -9094,6 +9190,9 @@ var VectorViewport = forwardRef(
|
|
|
9094
9190
|
}
|
|
9095
9191
|
const cam = cameraRef.current;
|
|
9096
9192
|
if (!cam) {
|
|
9193
|
+
if (st.kind === "stroke") {
|
|
9194
|
+
emitRemoteStrokePreviewClear();
|
|
9195
|
+
}
|
|
9097
9196
|
if (st.kind === "erase") {
|
|
9098
9197
|
eraserPreviewIdsRef.current.clear();
|
|
9099
9198
|
setEraserPreviewIds([]);
|
|
@@ -9325,6 +9424,8 @@ var VectorViewport = forwardRef(
|
|
|
9325
9424
|
document.removeEventListener("pointercancel", onUp);
|
|
9326
9425
|
};
|
|
9327
9426
|
}, [
|
|
9427
|
+
emitRemoteStrokePreview,
|
|
9428
|
+
emitRemoteStrokePreviewClear,
|
|
9328
9429
|
interactive,
|
|
9329
9430
|
pruneEraserTrail,
|
|
9330
9431
|
pruneLaserTrail,
|