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/index.cjs
CHANGED
|
@@ -85,6 +85,47 @@ var Camera2D = class {
|
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
+
// src/image/canvas-encode.ts
|
|
89
|
+
var DEFAULT_FALLBACK_MIME_TYPES = ["image/png"];
|
|
90
|
+
var tryCanvasToBlob = (canvas, mimeType, quality) => new Promise((resolve) => {
|
|
91
|
+
canvas.toBlob((blob) => resolve(blob), mimeType, quality);
|
|
92
|
+
});
|
|
93
|
+
var blobFromDataUrl = async (dataUrl) => {
|
|
94
|
+
const response = await fetch(dataUrl);
|
|
95
|
+
const blob = await response.blob();
|
|
96
|
+
if (blob.size === 0) {
|
|
97
|
+
throw new Error("Failed to encode canvas to blob");
|
|
98
|
+
}
|
|
99
|
+
return blob;
|
|
100
|
+
};
|
|
101
|
+
async function encodeCanvasToBlob(canvas, options) {
|
|
102
|
+
const primaryMimeType = options?.mimeType ?? "image/png";
|
|
103
|
+
const quality = options?.quality;
|
|
104
|
+
const mimeTypes = [
|
|
105
|
+
primaryMimeType,
|
|
106
|
+
...options?.fallbackMimeTypes ?? DEFAULT_FALLBACK_MIME_TYPES
|
|
107
|
+
].filter(
|
|
108
|
+
(mimeType, index, mimeTypeList) => mimeTypeList.indexOf(mimeType) === index
|
|
109
|
+
);
|
|
110
|
+
for (const mimeType of mimeTypes) {
|
|
111
|
+
const blob = await tryCanvasToBlob(
|
|
112
|
+
canvas,
|
|
113
|
+
mimeType,
|
|
114
|
+
mimeType === primaryMimeType ? quality : void 0
|
|
115
|
+
);
|
|
116
|
+
if (blob) {
|
|
117
|
+
return blob;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const mimeType of mimeTypes) {
|
|
121
|
+
const dataUrl = canvas.toDataURL(mimeType, quality);
|
|
122
|
+
if (dataUrl && dataUrl !== "data:,") {
|
|
123
|
+
return blobFromDataUrl(dataUrl);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
throw new Error("Failed to encode canvas to blob");
|
|
127
|
+
}
|
|
128
|
+
|
|
88
129
|
// src/image/indexed-db-image-store.ts
|
|
89
130
|
var DB_NAME = "canvu-image-store";
|
|
90
131
|
var DB_VERSION = 1;
|
|
@@ -200,21 +241,6 @@ async function renderPageToCanvas(page, scale) {
|
|
|
200
241
|
await page.render({ canvas, viewport }).promise;
|
|
201
242
|
return { canvas, width: w, height: h };
|
|
202
243
|
}
|
|
203
|
-
function canvasToBlob(canvas, mime, quality) {
|
|
204
|
-
return new Promise((resolve, reject) => {
|
|
205
|
-
canvas.toBlob(
|
|
206
|
-
(blob) => {
|
|
207
|
-
if (!blob) {
|
|
208
|
-
reject(new Error("Could not encode blob"));
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
resolve(blob);
|
|
212
|
-
},
|
|
213
|
-
mime,
|
|
214
|
-
quality
|
|
215
|
-
);
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
244
|
function normalizePdfPageNumbers(pageNumbers, pageCount) {
|
|
219
245
|
if (!pageNumbers || pageNumbers.length === 0) {
|
|
220
246
|
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
@@ -276,7 +302,7 @@ async function loadPdfToStore(file, store, options) {
|
|
|
276
302
|
const page = await pdf.getPage(pageNumber);
|
|
277
303
|
const { canvas, width, height } = await renderPageToCanvas(page, scale);
|
|
278
304
|
const mime = "image/png";
|
|
279
|
-
const pageBlob = await
|
|
305
|
+
const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
|
|
280
306
|
const blobId = await store.storeOriginal(pageBlob);
|
|
281
307
|
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
282
308
|
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
@@ -291,7 +317,9 @@ async function loadPdfToStore(file, store, options) {
|
|
|
291
317
|
tCtx.imageSmoothingQuality = "high";
|
|
292
318
|
tCtx.drawImage(canvas, 0, 0, tw, th);
|
|
293
319
|
}
|
|
294
|
-
const thumbBlob = await
|
|
320
|
+
const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
|
|
321
|
+
mimeType: mime
|
|
322
|
+
});
|
|
295
323
|
return await store.storeThumbnail(thumbBlob);
|
|
296
324
|
})() : "";
|
|
297
325
|
const pageResult = {
|
|
@@ -331,19 +359,9 @@ function loadImageFromObjectUrl(objectUrl) {
|
|
|
331
359
|
});
|
|
332
360
|
}
|
|
333
361
|
function canvasToObjectUrl(canvas, mime, quality) {
|
|
334
|
-
return
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (!blob) {
|
|
338
|
-
reject(new Error("Could not encode image blob"));
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
resolve(URL.createObjectURL(blob));
|
|
342
|
-
},
|
|
343
|
-
mime,
|
|
344
|
-
quality
|
|
345
|
-
);
|
|
346
|
-
});
|
|
362
|
+
return encodeCanvasToBlob(canvas, { mimeType: mime, quality }).then(
|
|
363
|
+
(blob) => URL.createObjectURL(blob)
|
|
364
|
+
);
|
|
347
365
|
}
|
|
348
366
|
async function loadImageFileAsRasterSceneSource(file, maxDimensionOrOptions) {
|
|
349
367
|
const { maxDimension: maxDim, embedMode } = normalizeLoadOptions(maxDimensionOrOptions);
|
|
@@ -561,16 +579,23 @@ function distanceBetween(a, b) {
|
|
|
561
579
|
function midpoint(a, b) {
|
|
562
580
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
563
581
|
}
|
|
564
|
-
function
|
|
565
|
-
switch (
|
|
582
|
+
function wheelDeltaPixels(delta, deltaMode) {
|
|
583
|
+
switch (deltaMode) {
|
|
566
584
|
case WheelEvent.DOM_DELTA_LINE:
|
|
567
|
-
return
|
|
585
|
+
return delta * 16;
|
|
568
586
|
case WheelEvent.DOM_DELTA_PAGE:
|
|
569
|
-
return
|
|
587
|
+
return delta * 400;
|
|
570
588
|
default:
|
|
571
|
-
return
|
|
589
|
+
return delta;
|
|
572
590
|
}
|
|
573
591
|
}
|
|
592
|
+
var TRACKPAD_MAX_DELTA = 20;
|
|
593
|
+
var MOUSE_WHEEL_DAMPING = 0.4;
|
|
594
|
+
function softenWheelDelta(d) {
|
|
595
|
+
const a = Math.abs(d);
|
|
596
|
+
if (a <= TRACKPAD_MAX_DELTA) return d;
|
|
597
|
+
return Math.sign(d) * (TRACKPAD_MAX_DELTA + (a - TRACKPAD_MAX_DELTA) * MOUSE_WHEEL_DAMPING);
|
|
598
|
+
}
|
|
574
599
|
function attachViewportInput(options) {
|
|
575
600
|
const {
|
|
576
601
|
element,
|
|
@@ -593,8 +618,8 @@ function attachViewportInput(options) {
|
|
|
593
618
|
const onWheel = (e) => {
|
|
594
619
|
if (e.ctrlKey || e.metaKey) {
|
|
595
620
|
e.preventDefault();
|
|
596
|
-
const dy =
|
|
597
|
-
const normDy = Math.abs(dy) <
|
|
621
|
+
const dy = wheelDeltaPixels(e.deltaY, e.deltaMode);
|
|
622
|
+
const normDy = Math.abs(dy) < TRACKPAD_MAX_DELTA ? dy * 12 : dy;
|
|
598
623
|
const factor = Math.exp(-normDy * wheelZoomSensitivity);
|
|
599
624
|
const rect = element.getBoundingClientRect();
|
|
600
625
|
camera.setZoom(camera.zoom * factor, {
|
|
@@ -605,8 +630,10 @@ function attachViewportInput(options) {
|
|
|
605
630
|
return;
|
|
606
631
|
}
|
|
607
632
|
e.preventDefault();
|
|
608
|
-
|
|
609
|
-
|
|
633
|
+
const panDx = softenWheelDelta(wheelDeltaPixels(e.deltaX, e.deltaMode));
|
|
634
|
+
const panDy = softenWheelDelta(wheelDeltaPixels(e.deltaY, e.deltaMode));
|
|
635
|
+
camera.x -= panDx * wheelPanSensitivity / camera.zoom;
|
|
636
|
+
camera.y -= panDy * wheelPanSensitivity / camera.zoom;
|
|
610
637
|
onUpdate();
|
|
611
638
|
};
|
|
612
639
|
const onPointerDown = (e) => {
|
|
@@ -2404,6 +2431,7 @@ exports.createShapeId = createShapeId;
|
|
|
2404
2431
|
exports.createTextItem = createTextItem;
|
|
2405
2432
|
exports.cullItemsByViewport = cullItemsByViewport;
|
|
2406
2433
|
exports.deleteManagedImage = deleteManagedImage;
|
|
2434
|
+
exports.encodeCanvasToBlob = encodeCanvasToBlob;
|
|
2407
2435
|
exports.expandCustomShapeTemplate = expandCustomShapeTemplate;
|
|
2408
2436
|
exports.formatCameraTransform = formatCameraTransform;
|
|
2409
2437
|
exports.formatItemPlacementTransform = formatItemPlacementTransform;
|