canvu-react 0.3.24 → 0.3.26
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 +1 -1
- package/dist/chatbot.d.ts +1 -1
- package/dist/index.cjs +49 -30
- 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 +49 -31
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +116 -33
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +116 -33
- package/dist/react.js.map +1 -1
- package/dist/realtime.cjs +21 -3
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js +21 -3
- package/dist/realtime.js.map +1 -1
- package/dist/{types-7kfWcm0L.d.cts → types-BLXR7g_L.d.cts} +7 -0
- package/dist/{types-C4k_AMvi.d.ts → types-Cm7IsgL4.d.ts} +7 -0
- 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 = {
|
|
@@ -6499,7 +6515,12 @@ function PresenceRemoteLayer({
|
|
|
6499
6515
|
const markup = peer.markupStroke;
|
|
6500
6516
|
let strokeNode = null;
|
|
6501
6517
|
if (markup && markup.points.length > 0) {
|
|
6502
|
-
const
|
|
6518
|
+
const fallbackPaint = strokePaint(markup.tool, color);
|
|
6519
|
+
const paint = {
|
|
6520
|
+
stroke: markup.stroke ?? fallbackPaint.stroke,
|
|
6521
|
+
strokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,
|
|
6522
|
+
widthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld
|
|
6523
|
+
};
|
|
6503
6524
|
const d = markup.points.length >= 2 ? smoothFreehandPointsToPathD([...markup.points]) : null;
|
|
6504
6525
|
if (d) {
|
|
6505
6526
|
strokeNode = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7405,6 +7426,41 @@ var VectorViewport = react.forwardRef(
|
|
|
7405
7426
|
onWorldPointerLeaveRef.current = onWorldPointerLeave;
|
|
7406
7427
|
const onPlacementPreviewChangeRef = react.useRef(onPlacementPreviewChange);
|
|
7407
7428
|
onPlacementPreviewChangeRef.current = onPlacementPreviewChange;
|
|
7429
|
+
const directRemoteStrokePreviewRef = react.useRef(false);
|
|
7430
|
+
const remoteStrokePreviewFrameRef = react.useRef(null);
|
|
7431
|
+
const pendingRemoteStrokePreviewRef = react.useRef(null);
|
|
7432
|
+
const flushRemoteStrokePreviewWithStyle = react.useCallback(() => {
|
|
7433
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7434
|
+
const pending = pendingRemoteStrokePreviewRef.current;
|
|
7435
|
+
if (!pending) return;
|
|
7436
|
+
onPlacementPreviewChangeRef.current?.({
|
|
7437
|
+
kind: "stroke",
|
|
7438
|
+
tool: pending.tool,
|
|
7439
|
+
points: pending.points,
|
|
7440
|
+
style: { ...strokeStyleRef.current }
|
|
7441
|
+
});
|
|
7442
|
+
}, []);
|
|
7443
|
+
const emitRemoteStrokePreview = react.useCallback(
|
|
7444
|
+
(tool, points) => {
|
|
7445
|
+
if (tool === "laser") return;
|
|
7446
|
+
directRemoteStrokePreviewRef.current = true;
|
|
7447
|
+
pendingRemoteStrokePreviewRef.current = { tool, points };
|
|
7448
|
+
if (remoteStrokePreviewFrameRef.current != null) return;
|
|
7449
|
+
remoteStrokePreviewFrameRef.current = requestAnimationFrame(
|
|
7450
|
+
flushRemoteStrokePreviewWithStyle
|
|
7451
|
+
);
|
|
7452
|
+
},
|
|
7453
|
+
[flushRemoteStrokePreviewWithStyle]
|
|
7454
|
+
);
|
|
7455
|
+
const emitRemoteStrokePreviewClear = react.useCallback(() => {
|
|
7456
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7457
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7458
|
+
remoteStrokePreviewFrameRef.current = null;
|
|
7459
|
+
}
|
|
7460
|
+
pendingRemoteStrokePreviewRef.current = null;
|
|
7461
|
+
directRemoteStrokePreviewRef.current = false;
|
|
7462
|
+
onPlacementPreviewChangeRef.current?.(null);
|
|
7463
|
+
}, []);
|
|
7408
7464
|
const overlayCameraTickRef = react.useRef(false);
|
|
7409
7465
|
overlayCameraTickRef.current = interactive || remotePresence != null && remotePresence.length > 0 || presenceOverlay != null;
|
|
7410
7466
|
const pruneEraserTrail = react.useCallback(
|
|
@@ -7523,6 +7579,7 @@ var VectorViewport = react.forwardRef(
|
|
|
7523
7579
|
if (itemId) {
|
|
7524
7580
|
renderSceneWithLivePenStroke(null);
|
|
7525
7581
|
}
|
|
7582
|
+
emitRemoteStrokePreviewClear();
|
|
7526
7583
|
setPlacementPreview(null);
|
|
7527
7584
|
commitCompletedStroke({
|
|
7528
7585
|
tool,
|
|
@@ -7534,6 +7591,7 @@ var VectorViewport = react.forwardRef(
|
|
|
7534
7591
|
},
|
|
7535
7592
|
[
|
|
7536
7593
|
commitCompletedStroke,
|
|
7594
|
+
emitRemoteStrokePreviewClear,
|
|
7537
7595
|
releaseInteractionPointer,
|
|
7538
7596
|
renderSceneWithLivePenStroke
|
|
7539
7597
|
]
|
|
@@ -7645,8 +7703,18 @@ var VectorViewport = react.forwardRef(
|
|
|
7645
7703
|
};
|
|
7646
7704
|
}, [onWorldPointerMove]);
|
|
7647
7705
|
react.useEffect(() => {
|
|
7706
|
+
if (directRemoteStrokePreviewRef.current && placementPreview === null) {
|
|
7707
|
+
return;
|
|
7708
|
+
}
|
|
7648
7709
|
onPlacementPreviewChangeRef.current?.(placementPreview);
|
|
7649
7710
|
}, [placementPreview]);
|
|
7711
|
+
react.useEffect(() => {
|
|
7712
|
+
return () => {
|
|
7713
|
+
if (remoteStrokePreviewFrameRef.current != null) {
|
|
7714
|
+
cancelAnimationFrame(remoteStrokePreviewFrameRef.current);
|
|
7715
|
+
}
|
|
7716
|
+
};
|
|
7717
|
+
}, []);
|
|
7650
7718
|
react.useEffect(() => {
|
|
7651
7719
|
const scene = sceneRef.current;
|
|
7652
7720
|
if (scene) {
|
|
@@ -8640,11 +8708,13 @@ var VectorViewport = react.forwardRef(
|
|
|
8640
8708
|
setPlacementPreview(null);
|
|
8641
8709
|
} else if (directPenStroke) {
|
|
8642
8710
|
setPlacementPreview(null);
|
|
8711
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8643
8712
|
} else {
|
|
8644
8713
|
setPlacementPreview({
|
|
8645
8714
|
kind: "stroke",
|
|
8646
8715
|
tool,
|
|
8647
|
-
points: [startPoint]
|
|
8716
|
+
points: [startPoint],
|
|
8717
|
+
style: { ...strokeStyleRef.current }
|
|
8648
8718
|
});
|
|
8649
8719
|
}
|
|
8650
8720
|
captureInteractionPointer(e.currentTarget, e.pointerId);
|
|
@@ -8681,6 +8751,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8681
8751
|
[
|
|
8682
8752
|
applePencilNav,
|
|
8683
8753
|
captureInteractionPointer,
|
|
8754
|
+
emitRemoteStrokePreview,
|
|
8684
8755
|
finalizeStrokeDragState,
|
|
8685
8756
|
renderSceneWithLivePenStroke,
|
|
8686
8757
|
screenToWorld
|
|
@@ -8739,6 +8810,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8739
8810
|
activeInteractionPointerIdRef.current = e.pointerId;
|
|
8740
8811
|
activeInteractionPointerTargetRef.current = null;
|
|
8741
8812
|
setPlacementPreview(null);
|
|
8813
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8742
8814
|
debugApplePencilPointer("native-pointerdown", {
|
|
8743
8815
|
pointerType: e.pointerType,
|
|
8744
8816
|
pointerId: e.pointerId,
|
|
@@ -8756,6 +8828,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8756
8828
|
};
|
|
8757
8829
|
}, [
|
|
8758
8830
|
applePencilNav,
|
|
8831
|
+
emitRemoteStrokePreview,
|
|
8759
8832
|
finalizeStrokeDragState,
|
|
8760
8833
|
interactive,
|
|
8761
8834
|
renderSceneWithLivePenStroke,
|
|
@@ -8839,6 +8912,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8839
8912
|
activeInteractionPointerTargetRef.current = null;
|
|
8840
8913
|
activeInteractionTouchIdRef.current = touch.identifier;
|
|
8841
8914
|
setPlacementPreview(null);
|
|
8915
|
+
emitRemoteStrokePreview(tool, [startPoint]);
|
|
8842
8916
|
debugApplePencilPointer("touchstart-stroke", {
|
|
8843
8917
|
touchId: touch.identifier,
|
|
8844
8918
|
touchType: touchKind(touch),
|
|
@@ -8870,6 +8944,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8870
8944
|
renderSceneWithLivePenStroke(item);
|
|
8871
8945
|
}
|
|
8872
8946
|
setPlacementPreview(null);
|
|
8947
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8873
8948
|
}
|
|
8874
8949
|
debugApplePencilPointer("touchmove-stroke", {
|
|
8875
8950
|
touchId: touch.identifier,
|
|
@@ -8932,6 +9007,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8932
9007
|
};
|
|
8933
9008
|
}, [
|
|
8934
9009
|
applePencilNav,
|
|
9010
|
+
emitRemoteStrokePreview,
|
|
8935
9011
|
finalizeStrokeDragState,
|
|
8936
9012
|
interactive,
|
|
8937
9013
|
renderSceneWithLivePenStroke,
|
|
@@ -8986,6 +9062,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8986
9062
|
renderSceneWithLivePenStroke(item);
|
|
8987
9063
|
}
|
|
8988
9064
|
setPlacementPreview(null);
|
|
9065
|
+
emitRemoteStrokePreview(st.tool, interpolated);
|
|
8989
9066
|
return;
|
|
8990
9067
|
}
|
|
8991
9068
|
if (st.tool === "laser") {
|
|
@@ -9004,7 +9081,8 @@ var VectorViewport = react.forwardRef(
|
|
|
9004
9081
|
setPlacementPreview({
|
|
9005
9082
|
kind: "stroke",
|
|
9006
9083
|
tool: st.tool,
|
|
9007
|
-
points: interpolated
|
|
9084
|
+
points: interpolated,
|
|
9085
|
+
style: { ...strokeStyleRef.current }
|
|
9008
9086
|
});
|
|
9009
9087
|
}
|
|
9010
9088
|
return;
|
|
@@ -9127,6 +9205,9 @@ var VectorViewport = react.forwardRef(
|
|
|
9127
9205
|
}
|
|
9128
9206
|
const cam = cameraRef.current;
|
|
9129
9207
|
if (!cam) {
|
|
9208
|
+
if (st.kind === "stroke") {
|
|
9209
|
+
emitRemoteStrokePreviewClear();
|
|
9210
|
+
}
|
|
9130
9211
|
if (st.kind === "erase") {
|
|
9131
9212
|
eraserPreviewIdsRef.current.clear();
|
|
9132
9213
|
setEraserPreviewIds([]);
|
|
@@ -9358,6 +9439,8 @@ var VectorViewport = react.forwardRef(
|
|
|
9358
9439
|
document.removeEventListener("pointercancel", onUp);
|
|
9359
9440
|
};
|
|
9360
9441
|
}, [
|
|
9442
|
+
emitRemoteStrokePreview,
|
|
9443
|
+
emitRemoteStrokePreviewClear,
|
|
9361
9444
|
interactive,
|
|
9362
9445
|
pruneEraserTrail,
|
|
9363
9446
|
pruneLaserTrail,
|