canvu-react 0.3.13 → 0.3.14
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/README.md +9 -1
- package/dist/index.cjs +41 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -15
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +100 -67
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +9 -1
- package/dist/react.d.ts +9 -1
- package/dist/react.js +100 -67
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -956,10 +956,32 @@ async function runWithConcurrency(items, concurrency, execute) {
|
|
|
956
956
|
async function loadPdfToStore(file, store, options) {
|
|
957
957
|
const scale = options?.scale ?? 1.5;
|
|
958
958
|
const pageConcurrency = options?.pageConcurrency ?? 2;
|
|
959
|
+
const storeThumbnails = options?.storeThumbnails ?? false;
|
|
959
960
|
const pdfjs = await getPdfJs();
|
|
960
961
|
const arrayBuffer = await file.arrayBuffer();
|
|
961
962
|
const pdf = await pdfjs.getDocument({ data: arrayBuffer }).promise;
|
|
962
963
|
const pageNumbers = normalizePdfPageNumbers(options?.pageNumbers, pdf.numPages);
|
|
964
|
+
const bufferedResults = /* @__PURE__ */ new Map();
|
|
965
|
+
let nextEmitIndex = 0;
|
|
966
|
+
let emitChain = Promise.resolve();
|
|
967
|
+
const queuePageEmission = async (pageResult) => {
|
|
968
|
+
bufferedResults.set(pageResult.pageNumber, pageResult);
|
|
969
|
+
const run = async () => {
|
|
970
|
+
while (nextEmitIndex < pageNumbers.length) {
|
|
971
|
+
const nextPageNumber = pageNumbers[nextEmitIndex];
|
|
972
|
+
if (nextPageNumber == null) break;
|
|
973
|
+
const bufferedResult = bufferedResults.get(nextPageNumber);
|
|
974
|
+
if (!bufferedResult) break;
|
|
975
|
+
bufferedResults.delete(nextPageNumber);
|
|
976
|
+
nextEmitIndex += 1;
|
|
977
|
+
await options?.onPageStored?.(bufferedResult);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
const nextChain = emitChain.then(run, run);
|
|
981
|
+
emitChain = nextChain.catch(() => {
|
|
982
|
+
});
|
|
983
|
+
await nextChain;
|
|
984
|
+
};
|
|
963
985
|
return await runWithConcurrency(
|
|
964
986
|
pageNumbers,
|
|
965
987
|
pageConcurrency,
|
|
@@ -969,27 +991,31 @@ async function loadPdfToStore(file, store, options) {
|
|
|
969
991
|
const mime = "image/png";
|
|
970
992
|
const pageBlob = await canvasToBlob2(canvas, mime);
|
|
971
993
|
const blobId = await store.storeOriginal(pageBlob);
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
tCtx
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
994
|
+
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
995
|
+
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
996
|
+
const tw = Math.max(1, Math.round(width * thumbScale));
|
|
997
|
+
const th = Math.max(1, Math.round(height * thumbScale));
|
|
998
|
+
const thumbCanvas = document.createElement("canvas");
|
|
999
|
+
thumbCanvas.width = tw;
|
|
1000
|
+
thumbCanvas.height = th;
|
|
1001
|
+
const tCtx = thumbCanvas.getContext("2d");
|
|
1002
|
+
if (tCtx) {
|
|
1003
|
+
tCtx.imageSmoothingEnabled = true;
|
|
1004
|
+
tCtx.imageSmoothingQuality = "high";
|
|
1005
|
+
tCtx.drawImage(canvas, 0, 0, tw, th);
|
|
1006
|
+
}
|
|
1007
|
+
const thumbBlob = await canvasToBlob2(thumbCanvas, mime);
|
|
1008
|
+
return await store.storeThumbnail(thumbBlob);
|
|
1009
|
+
})() : "";
|
|
1010
|
+
const pageResult = {
|
|
987
1011
|
blobId,
|
|
988
1012
|
thumbnailBlobId,
|
|
989
1013
|
width,
|
|
990
1014
|
height,
|
|
991
1015
|
pageNumber
|
|
992
1016
|
};
|
|
1017
|
+
await queuePageEmission(pageResult);
|
|
1018
|
+
return pageResult;
|
|
993
1019
|
}
|
|
994
1020
|
);
|
|
995
1021
|
}
|
|
@@ -1345,9 +1371,10 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
1345
1371
|
createId = createShapeId,
|
|
1346
1372
|
gapWorld = 16,
|
|
1347
1373
|
stepWorld = 48,
|
|
1348
|
-
pdfScale = 1.
|
|
1374
|
+
pdfScale = 1.15,
|
|
1349
1375
|
pdfPageConcurrency = 2,
|
|
1350
1376
|
decorateItem,
|
|
1377
|
+
onItemsReady,
|
|
1351
1378
|
onError
|
|
1352
1379
|
} = options;
|
|
1353
1380
|
const items = [];
|
|
@@ -1369,55 +1396,56 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
1369
1396
|
}
|
|
1370
1397
|
try {
|
|
1371
1398
|
if (kind === "pdf") {
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1399
|
+
const uploadResultPromise = uploadAssetIfNeeded(assetStore, file, kind);
|
|
1400
|
+
await loadPdfToStore(file, imageStore, {
|
|
1401
|
+
scale: pdfScale,
|
|
1402
|
+
pageConcurrency: pdfPageConcurrency,
|
|
1403
|
+
storeThumbnails: false,
|
|
1404
|
+
onPageStored: async (page) => {
|
|
1405
|
+
const uploadResult2 = await uploadResultPromise;
|
|
1406
|
+
const fullUrl2 = await createBlobUrlFromStore(imageStore, page.blobId);
|
|
1407
|
+
const naturalTopY2 = worldCenter.y - page.height / 2;
|
|
1408
|
+
const stackedTopY = occupiedBottomY == null ? naturalTopY2 : occupiedBottomY + gapWorld;
|
|
1409
|
+
const bounds2 = {
|
|
1410
|
+
x: worldCenter.x - page.width / 2,
|
|
1411
|
+
y: Math.max(naturalTopY2, stackedTopY),
|
|
1412
|
+
width: page.width,
|
|
1413
|
+
height: page.height
|
|
1414
|
+
};
|
|
1415
|
+
const itemContext2 = {
|
|
1416
|
+
file,
|
|
1417
|
+
kind,
|
|
1418
|
+
itemIndex: items.length,
|
|
1419
|
+
pageNumber: page.pageNumber
|
|
1420
|
+
};
|
|
1421
|
+
const item2 = finalizeIngestedItem(
|
|
1422
|
+
{
|
|
1423
|
+
id: createId(),
|
|
1424
|
+
x: bounds2.x,
|
|
1425
|
+
y: bounds2.y,
|
|
1426
|
+
bounds: { ...bounds2 },
|
|
1427
|
+
toolKind: "image",
|
|
1428
|
+
imageBlobId: page.blobId,
|
|
1429
|
+
imageRasterHref: fullUrl2 ?? void 0,
|
|
1430
|
+
imageIntrinsicSize: {
|
|
1431
|
+
width: page.width,
|
|
1432
|
+
height: page.height
|
|
1433
|
+
},
|
|
1434
|
+
childrenSvg: fullUrl2 ? buildRasterImageChildrenSvg(
|
|
1435
|
+
fullUrl2,
|
|
1436
|
+
{ width: page.width, height: page.height },
|
|
1437
|
+
bounds2
|
|
1438
|
+
) : ""
|
|
1407
1439
|
},
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
);
|
|
1418
|
-
items.push(item2);
|
|
1419
|
-
occupiedBottomY = bounds2.y + page.height;
|
|
1420
|
-
}
|
|
1440
|
+
itemContext2,
|
|
1441
|
+
uploadResult2,
|
|
1442
|
+
decorateItem
|
|
1443
|
+
);
|
|
1444
|
+
items.push(item2);
|
|
1445
|
+
occupiedBottomY = bounds2.y + page.height;
|
|
1446
|
+
onItemsReady?.([item2], { file, kind });
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1421
1449
|
hasImagePlacementBase = false;
|
|
1422
1450
|
imagePlacementIndex = 0;
|
|
1423
1451
|
imageYOffsetAdjustment = 0;
|
|
@@ -1470,6 +1498,7 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
1470
1498
|
decorateItem
|
|
1471
1499
|
);
|
|
1472
1500
|
items.push(item);
|
|
1501
|
+
onItemsReady?.([item], { file, kind });
|
|
1473
1502
|
imagePlacementIndex++;
|
|
1474
1503
|
occupiedBottomY = occupiedBottomY == null ? bounds.y + height : Math.max(occupiedBottomY, bounds.y + height);
|
|
1475
1504
|
} catch (error) {
|
|
@@ -7382,7 +7411,13 @@ var VectorViewport = react.forwardRef(
|
|
|
7382
7411
|
y: worldY
|
|
7383
7412
|
},
|
|
7384
7413
|
imageStore: store,
|
|
7385
|
-
assetStore: assetStoreRef.current ?? void 0
|
|
7414
|
+
assetStore: assetStoreRef.current ?? void 0,
|
|
7415
|
+
onItemsReady: (nextItems) => {
|
|
7416
|
+
if (nextItems.length === 0) return;
|
|
7417
|
+
setLoadingSkeletons([]);
|
|
7418
|
+
change([...itemsRef.current, ...nextItems]);
|
|
7419
|
+
setEffectiveSelectedIdsRef.current(nextItems.map((item) => item.id));
|
|
7420
|
+
}
|
|
7386
7421
|
});
|
|
7387
7422
|
if (result.errors.length > 0) {
|
|
7388
7423
|
for (const error of result.errors) {
|
|
@@ -7390,8 +7425,6 @@ var VectorViewport = react.forwardRef(
|
|
|
7390
7425
|
}
|
|
7391
7426
|
}
|
|
7392
7427
|
if (result.items.length === 0) return;
|
|
7393
|
-
change([...itemsRef.current, ...result.items]);
|
|
7394
|
-
setEffectiveSelectedIdsRef.current(result.items.map((item) => item.id));
|
|
7395
7428
|
} finally {
|
|
7396
7429
|
setLoadingSkeletons([]);
|
|
7397
7430
|
}
|