canvu-react 0.4.66 → 0.4.68
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/{asset-hydration-F6aM5C7x.d.cts → asset-hydration-Dw99FGJB.d.cts} +1 -1
- package/dist/{asset-hydration-BSjiek7Q.d.ts → asset-hydration-aNXfeayg.d.ts} +1 -1
- package/dist/chatbot.d.cts +2 -2
- package/dist/chatbot.d.ts +2 -2
- package/dist/index.cjs +466 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +466 -0
- package/dist/index.js.map +1 -1
- package/dist/{asset-store-35ysK28r.d.cts → raster-image-canvas-BZh73aoc.d.ts} +70 -2
- package/dist/{asset-store-D_FjW_CN.d.ts → raster-image-canvas-zerVYllB.d.cts} +70 -2
- package/dist/react.cjs +487 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -6
- package/dist/react.d.ts +6 -6
- package/dist/react.js +487 -2
- package/dist/react.js.map +1 -1
- 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.map +1 -1
- package/dist/{types-B-Jdh-n6.d.ts → types-94XpQMy7.d.ts} +12 -1
- package/dist/{types-D5d-3dvz.d.cts → types-BZ9wK9Y3.d.cts} +12 -1
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { V as VectorSceneItem } from './types-fJNwEnHf.cjs';
|
|
2
2
|
export { C as CustomShapeResizeHandles, b as ResizeHandleId } from './types-fJNwEnHf.cjs';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
7
|
-
import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-
|
|
8
|
-
export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-
|
|
3
|
+
import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './raster-image-canvas-zerVYllB.cjs';
|
|
4
|
+
export { b as RasterImageCanvasRenderRequest, c as RasterImageCanvasRenderTarget, d as RasterImageCanvasRenderTargetResolver, R as RasterImageCanvasRenderingOptions, e as VectorViewportAssetHydrationRequest, f as VectorViewportAssetResolveRequest, g as VectorViewportAssetResolveResult, h as VectorViewportAssetUploadRequest, i as VectorViewportAssetUploadResult } from './raster-image-canvas-zerVYllB.cjs';
|
|
5
|
+
import { I as IndexedDbImageStore } from './asset-hydration-Dw99FGJB.cjs';
|
|
6
|
+
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-Dw99FGJB.cjs';
|
|
7
|
+
import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-BZ9wK9Y3.cjs';
|
|
8
|
+
export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-BZ9wK9Y3.cjs';
|
|
9
9
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
10
10
|
import * as react from 'react';
|
|
11
11
|
import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
|
package/dist/react.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { V as VectorSceneItem } from './types-fJNwEnHf.js';
|
|
2
2
|
export { C as CustomShapeResizeHandles, b as ResizeHandleId } from './types-fJNwEnHf.js';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
7
|
-
import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-
|
|
8
|
-
export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-
|
|
3
|
+
import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './raster-image-canvas-BZh73aoc.js';
|
|
4
|
+
export { b as RasterImageCanvasRenderRequest, c as RasterImageCanvasRenderTarget, d as RasterImageCanvasRenderTargetResolver, R as RasterImageCanvasRenderingOptions, e as VectorViewportAssetHydrationRequest, f as VectorViewportAssetResolveRequest, g as VectorViewportAssetResolveResult, h as VectorViewportAssetUploadRequest, i as VectorViewportAssetUploadResult } from './raster-image-canvas-BZh73aoc.js';
|
|
5
|
+
import { I as IndexedDbImageStore } from './asset-hydration-aNXfeayg.js';
|
|
6
|
+
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-aNXfeayg.js';
|
|
7
|
+
import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-94XpQMy7.js';
|
|
8
|
+
export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-94XpQMy7.js';
|
|
9
9
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
10
10
|
import * as react from 'react';
|
|
11
11
|
import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
|
package/dist/react.js
CHANGED
|
@@ -6877,6 +6877,152 @@ function cullItemsByViewport(items, visibleWorld) {
|
|
|
6877
6877
|
return cullItemsByViewportSpatial(items, visibleWorld, SPATIAL_CELL_SIZE);
|
|
6878
6878
|
}
|
|
6879
6879
|
|
|
6880
|
+
// src/renderer/raster-image-canvas.ts
|
|
6881
|
+
init_rect();
|
|
6882
|
+
var DEFAULT_PIXEL_HEADROOM = 1.5;
|
|
6883
|
+
var DEFAULT_MAX_PIXEL_COUNT = 12e6;
|
|
6884
|
+
var DEFAULT_MAX_DIMENSION = 4096;
|
|
6885
|
+
var DEFAULT_UPSCALE_REDRAW_RATIO = 1.15;
|
|
6886
|
+
function resolveRasterImageCanvasRenderingOptions(options) {
|
|
6887
|
+
if (!options) return null;
|
|
6888
|
+
const fallbackDevicePixelRatio = typeof window === "undefined" ? 1 : window.devicePixelRatio;
|
|
6889
|
+
return {
|
|
6890
|
+
resolveRenderTarget: options.resolveRenderTarget,
|
|
6891
|
+
devicePixelRatio: toPositiveFiniteNumber(
|
|
6892
|
+
options.devicePixelRatio,
|
|
6893
|
+
fallbackDevicePixelRatio
|
|
6894
|
+
),
|
|
6895
|
+
pixelHeadroom: toPositiveFiniteNumber(
|
|
6896
|
+
options.pixelHeadroom,
|
|
6897
|
+
DEFAULT_PIXEL_HEADROOM
|
|
6898
|
+
),
|
|
6899
|
+
maxPixelCount: toPositiveFiniteNumber(
|
|
6900
|
+
options.maxPixelCount,
|
|
6901
|
+
DEFAULT_MAX_PIXEL_COUNT
|
|
6902
|
+
),
|
|
6903
|
+
maxDimension: toPositiveFiniteNumber(
|
|
6904
|
+
options.maxDimension,
|
|
6905
|
+
DEFAULT_MAX_DIMENSION
|
|
6906
|
+
),
|
|
6907
|
+
upscaleRedrawRatio: toPositiveFiniteNumber(
|
|
6908
|
+
options.upscaleRedrawRatio,
|
|
6909
|
+
DEFAULT_UPSCALE_REDRAW_RATIO
|
|
6910
|
+
)
|
|
6911
|
+
};
|
|
6912
|
+
}
|
|
6913
|
+
function getRasterImageContentRect(item) {
|
|
6914
|
+
if (item.toolKind !== "image" || !item.imageIntrinsicSize) return null;
|
|
6915
|
+
const bounds = normalizeRect(item.bounds);
|
|
6916
|
+
const intrinsicWidth = Math.max(1e-6, item.imageIntrinsicSize.width);
|
|
6917
|
+
const intrinsicHeight = Math.max(1e-6, item.imageIntrinsicSize.height);
|
|
6918
|
+
const boundsAspectRatio = bounds.width / Math.max(1e-9, bounds.height);
|
|
6919
|
+
const imageAspectRatio = intrinsicWidth / intrinsicHeight;
|
|
6920
|
+
if (Math.abs(boundsAspectRatio - imageAspectRatio) < 1e-3) {
|
|
6921
|
+
return { x: 0, y: 0, width: bounds.width, height: bounds.height };
|
|
6922
|
+
}
|
|
6923
|
+
if (boundsAspectRatio > imageAspectRatio) {
|
|
6924
|
+
const height2 = bounds.height;
|
|
6925
|
+
const width2 = height2 * imageAspectRatio;
|
|
6926
|
+
return { x: (bounds.width - width2) / 2, y: 0, width: width2, height: height2 };
|
|
6927
|
+
}
|
|
6928
|
+
const width = bounds.width;
|
|
6929
|
+
const height = width / imageAspectRatio;
|
|
6930
|
+
return { x: 0, y: (bounds.height - height) / 2, width, height };
|
|
6931
|
+
}
|
|
6932
|
+
function getRasterImageCanvasTargetSize({
|
|
6933
|
+
intrinsicSize,
|
|
6934
|
+
contentRect,
|
|
6935
|
+
cameraZoom,
|
|
6936
|
+
devicePixelRatio,
|
|
6937
|
+
pixelHeadroom,
|
|
6938
|
+
maxPixelCount,
|
|
6939
|
+
maxDimension
|
|
6940
|
+
}) {
|
|
6941
|
+
const intrinsicWidth = Math.max(1, Math.round(intrinsicSize.width));
|
|
6942
|
+
const intrinsicHeight = Math.max(1, Math.round(intrinsicSize.height));
|
|
6943
|
+
const targetCssWidth = Math.max(1, contentRect.width * cameraZoom);
|
|
6944
|
+
const targetCssHeight = Math.max(1, contentRect.height * cameraZoom);
|
|
6945
|
+
const desiredWidth = targetCssWidth * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
|
|
6946
|
+
const desiredHeight = targetCssHeight * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
|
|
6947
|
+
const dimensionScale = Math.min(
|
|
6948
|
+
1,
|
|
6949
|
+
toPositiveFiniteNumber(maxDimension, intrinsicWidth) / Math.max(intrinsicWidth, intrinsicHeight)
|
|
6950
|
+
);
|
|
6951
|
+
const pixelScale = Math.min(
|
|
6952
|
+
1,
|
|
6953
|
+
Math.sqrt(
|
|
6954
|
+
toPositiveFiniteNumber(maxPixelCount, intrinsicWidth * intrinsicHeight) / (intrinsicWidth * intrinsicHeight)
|
|
6955
|
+
)
|
|
6956
|
+
);
|
|
6957
|
+
const viewportScale = Math.min(
|
|
6958
|
+
1,
|
|
6959
|
+
desiredWidth / intrinsicWidth,
|
|
6960
|
+
desiredHeight / intrinsicHeight
|
|
6961
|
+
);
|
|
6962
|
+
const scale = Math.min(dimensionScale, pixelScale, viewportScale);
|
|
6963
|
+
const width = Math.max(1, Math.round(intrinsicWidth * scale));
|
|
6964
|
+
const height = Math.max(1, Math.round(width * (intrinsicHeight / intrinsicWidth)));
|
|
6965
|
+
return { width, height };
|
|
6966
|
+
}
|
|
6967
|
+
function resolveRasterImageCanvasRenderTarget({
|
|
6968
|
+
item,
|
|
6969
|
+
href,
|
|
6970
|
+
intrinsicSize,
|
|
6971
|
+
contentRect,
|
|
6972
|
+
targetSize,
|
|
6973
|
+
viewportSize,
|
|
6974
|
+
cameraZoom,
|
|
6975
|
+
options
|
|
6976
|
+
}) {
|
|
6977
|
+
const request = {
|
|
6978
|
+
item,
|
|
6979
|
+
href,
|
|
6980
|
+
intrinsicSize,
|
|
6981
|
+
contentRect,
|
|
6982
|
+
targetSize,
|
|
6983
|
+
viewportSize,
|
|
6984
|
+
cameraZoom,
|
|
6985
|
+
devicePixelRatio: options.devicePixelRatio
|
|
6986
|
+
};
|
|
6987
|
+
const resolved = options.resolveRenderTarget?.(request);
|
|
6988
|
+
if (typeof resolved === "string") {
|
|
6989
|
+
return { href: resolved, sourceKey: resolved, targetSize, contentRect };
|
|
6990
|
+
}
|
|
6991
|
+
if (resolved?.href) {
|
|
6992
|
+
return {
|
|
6993
|
+
href: resolved.href,
|
|
6994
|
+
sourceKey: resolved.sourceKey ?? resolved.href,
|
|
6995
|
+
targetSize,
|
|
6996
|
+
contentRect
|
|
6997
|
+
};
|
|
6998
|
+
}
|
|
6999
|
+
return { href, sourceKey: href, targetSize, contentRect };
|
|
7000
|
+
}
|
|
7001
|
+
function shouldRedrawRasterImageCanvas({
|
|
7002
|
+
currentSourceKey,
|
|
7003
|
+
currentWidth,
|
|
7004
|
+
currentHeight,
|
|
7005
|
+
nextSourceKey,
|
|
7006
|
+
nextWidth,
|
|
7007
|
+
nextHeight,
|
|
7008
|
+
upscaleRedrawRatio
|
|
7009
|
+
}) {
|
|
7010
|
+
const safeCurrentWidth = Math.max(0, Math.round(currentWidth));
|
|
7011
|
+
const safeCurrentHeight = Math.max(0, Math.round(currentHeight));
|
|
7012
|
+
const safeNextWidth = Math.max(1, Math.round(nextWidth));
|
|
7013
|
+
const safeNextHeight = Math.max(1, Math.round(nextHeight));
|
|
7014
|
+
if (!currentSourceKey || safeCurrentWidth <= 1 || safeCurrentHeight <= 1) {
|
|
7015
|
+
return true;
|
|
7016
|
+
}
|
|
7017
|
+
if (currentSourceKey !== nextSourceKey && safeCurrentWidth === safeNextWidth && safeCurrentHeight === safeNextHeight) {
|
|
7018
|
+
return true;
|
|
7019
|
+
}
|
|
7020
|
+
return safeNextWidth > safeCurrentWidth * upscaleRedrawRatio || safeNextHeight > safeCurrentHeight * upscaleRedrawRatio;
|
|
7021
|
+
}
|
|
7022
|
+
function toPositiveFiniteNumber(value, fallback) {
|
|
7023
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
7024
|
+
}
|
|
7025
|
+
|
|
6880
7026
|
// src/renderer/svg-vector-renderer.ts
|
|
6881
7027
|
function formatCameraTransform(camera) {
|
|
6882
7028
|
const z = camera.zoom;
|
|
@@ -6901,6 +7047,87 @@ function itemClassName(item) {
|
|
|
6901
7047
|
}
|
|
6902
7048
|
return classes.join(" ");
|
|
6903
7049
|
}
|
|
7050
|
+
async function decodeRasterImage(href, width, height, signal) {
|
|
7051
|
+
if (typeof createImageBitmap === "function") {
|
|
7052
|
+
try {
|
|
7053
|
+
const response = await fetch(href, { signal, credentials: "same-origin" });
|
|
7054
|
+
if (!response.ok) {
|
|
7055
|
+
throw new Error(`Failed to fetch raster image: ${response.status}`);
|
|
7056
|
+
}
|
|
7057
|
+
const blob = await response.blob();
|
|
7058
|
+
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
7059
|
+
const bitmap = await createImageBitmap(blob, {
|
|
7060
|
+
resizeWidth: width,
|
|
7061
|
+
resizeHeight: height,
|
|
7062
|
+
resizeQuality: "high"
|
|
7063
|
+
});
|
|
7064
|
+
return {
|
|
7065
|
+
width: bitmap.width,
|
|
7066
|
+
height: bitmap.height,
|
|
7067
|
+
draw: (context) => {
|
|
7068
|
+
context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
|
|
7069
|
+
},
|
|
7070
|
+
close: () => bitmap.close()
|
|
7071
|
+
};
|
|
7072
|
+
} catch (error) {
|
|
7073
|
+
if (signal.aborted) throw error;
|
|
7074
|
+
}
|
|
7075
|
+
}
|
|
7076
|
+
const image = await loadImageElement(href, signal);
|
|
7077
|
+
return {
|
|
7078
|
+
width,
|
|
7079
|
+
height,
|
|
7080
|
+
draw: (context) => {
|
|
7081
|
+
context.drawImage(image, 0, 0, width, height);
|
|
7082
|
+
},
|
|
7083
|
+
close: () => {
|
|
7084
|
+
}
|
|
7085
|
+
};
|
|
7086
|
+
}
|
|
7087
|
+
function loadImageElement(href, signal) {
|
|
7088
|
+
return new Promise((resolve, reject) => {
|
|
7089
|
+
if (signal.aborted) {
|
|
7090
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
7091
|
+
return;
|
|
7092
|
+
}
|
|
7093
|
+
const image = new Image();
|
|
7094
|
+
const cleanup = () => {
|
|
7095
|
+
signal.removeEventListener("abort", abort);
|
|
7096
|
+
image.onload = null;
|
|
7097
|
+
image.onerror = null;
|
|
7098
|
+
};
|
|
7099
|
+
const abort = () => {
|
|
7100
|
+
cleanup();
|
|
7101
|
+
image.removeAttribute("src");
|
|
7102
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
7103
|
+
};
|
|
7104
|
+
image.decoding = "async";
|
|
7105
|
+
image.onload = () => {
|
|
7106
|
+
const decodePromise = image.decode?.();
|
|
7107
|
+
if (!decodePromise) {
|
|
7108
|
+
cleanup();
|
|
7109
|
+
resolve(image);
|
|
7110
|
+
return;
|
|
7111
|
+
}
|
|
7112
|
+
decodePromise.then(
|
|
7113
|
+
() => {
|
|
7114
|
+
cleanup();
|
|
7115
|
+
resolve(image);
|
|
7116
|
+
},
|
|
7117
|
+
() => {
|
|
7118
|
+
cleanup();
|
|
7119
|
+
resolve(image);
|
|
7120
|
+
}
|
|
7121
|
+
);
|
|
7122
|
+
};
|
|
7123
|
+
image.onerror = () => {
|
|
7124
|
+
cleanup();
|
|
7125
|
+
reject(new Error("Failed to load raster image"));
|
|
7126
|
+
};
|
|
7127
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
7128
|
+
image.src = href;
|
|
7129
|
+
});
|
|
7130
|
+
}
|
|
6904
7131
|
var SvgVectorRenderer = class {
|
|
6905
7132
|
container;
|
|
6906
7133
|
scene;
|
|
@@ -6912,10 +7139,14 @@ var SvgVectorRenderer = class {
|
|
|
6912
7139
|
hoveredItemId = null;
|
|
6913
7140
|
liveOverlay = null;
|
|
6914
7141
|
resizeObserver;
|
|
7142
|
+
rasterImageCanvasRendering;
|
|
6915
7143
|
constructor(options) {
|
|
6916
7144
|
this.container = options.container;
|
|
6917
7145
|
this.scene = options.scene;
|
|
6918
7146
|
this.camera = options.camera;
|
|
7147
|
+
this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(
|
|
7148
|
+
options.rasterImageCanvas
|
|
7149
|
+
);
|
|
6919
7150
|
this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
6920
7151
|
this.svg.setAttribute("width", "100%");
|
|
6921
7152
|
this.svg.setAttribute("height", "100%");
|
|
@@ -6944,6 +7175,15 @@ var SvgVectorRenderer = class {
|
|
|
6944
7175
|
this.applyInteractionAttributes(cached.g, id);
|
|
6945
7176
|
}
|
|
6946
7177
|
}
|
|
7178
|
+
setRasterImageCanvasRendering(options) {
|
|
7179
|
+
this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(options);
|
|
7180
|
+
if (!this.rasterImageCanvasRendering) {
|
|
7181
|
+
for (const cached of this.itemNodeCache.values()) {
|
|
7182
|
+
this.releaseRasterImageCanvas(cached);
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
this.render();
|
|
7186
|
+
}
|
|
6947
7187
|
/**
|
|
6948
7188
|
* Reads container size, culls items, and updates the SVG (incrementally when possible).
|
|
6949
7189
|
*/
|
|
@@ -7017,6 +7257,7 @@ var SvgVectorRenderer = class {
|
|
|
7017
7257
|
}
|
|
7018
7258
|
for (const [id, cached] of this.itemNodeCache) {
|
|
7019
7259
|
if (!visibleIds.has(id)) {
|
|
7260
|
+
this.releaseRasterImageCanvas(cached);
|
|
7020
7261
|
cached.g.remove();
|
|
7021
7262
|
}
|
|
7022
7263
|
}
|
|
@@ -7049,6 +7290,7 @@ var SvgVectorRenderer = class {
|
|
|
7049
7290
|
g.innerHTML = item.childrenSvg;
|
|
7050
7291
|
cached.lastChildrenSvg = item.childrenSvg;
|
|
7051
7292
|
}
|
|
7293
|
+
this.syncRasterImageCanvas(cached, item);
|
|
7052
7294
|
const expectedPosition = previousNode ? previousNode.nextSibling : this.rootG.firstChild;
|
|
7053
7295
|
if (expectedPosition !== g) {
|
|
7054
7296
|
this.rootG.insertBefore(g, expectedPosition);
|
|
@@ -7056,6 +7298,228 @@ var SvgVectorRenderer = class {
|
|
|
7056
7298
|
previousNode = g;
|
|
7057
7299
|
}
|
|
7058
7300
|
}
|
|
7301
|
+
syncRasterImageCanvas(cached, item) {
|
|
7302
|
+
const options = this.rasterImageCanvasRendering;
|
|
7303
|
+
if (!options || item.toolKind !== "image" || !item.imageRasterHref || !item.imageIntrinsicSize) {
|
|
7304
|
+
this.releaseRasterImageCanvas(cached);
|
|
7305
|
+
return;
|
|
7306
|
+
}
|
|
7307
|
+
const contentRect = getRasterImageContentRect(item);
|
|
7308
|
+
const viewportSize = {
|
|
7309
|
+
width: this.container.clientWidth,
|
|
7310
|
+
height: this.container.clientHeight
|
|
7311
|
+
};
|
|
7312
|
+
if (!contentRect || viewportSize.width <= 0 || viewportSize.height <= 0) {
|
|
7313
|
+
this.releaseRasterImageCanvas(cached);
|
|
7314
|
+
return;
|
|
7315
|
+
}
|
|
7316
|
+
const targetSize = getRasterImageCanvasTargetSize({
|
|
7317
|
+
intrinsicSize: item.imageIntrinsicSize,
|
|
7318
|
+
contentRect,
|
|
7319
|
+
cameraZoom: this.camera.zoom,
|
|
7320
|
+
devicePixelRatio: options.devicePixelRatio,
|
|
7321
|
+
pixelHeadroom: options.pixelHeadroom,
|
|
7322
|
+
maxPixelCount: options.maxPixelCount,
|
|
7323
|
+
maxDimension: options.maxDimension
|
|
7324
|
+
});
|
|
7325
|
+
const target = resolveRasterImageCanvasRenderTarget({
|
|
7326
|
+
item,
|
|
7327
|
+
href: item.imageRasterHref,
|
|
7328
|
+
intrinsicSize: item.imageIntrinsicSize,
|
|
7329
|
+
contentRect,
|
|
7330
|
+
targetSize,
|
|
7331
|
+
viewportSize,
|
|
7332
|
+
cameraZoom: this.camera.zoom,
|
|
7333
|
+
options
|
|
7334
|
+
});
|
|
7335
|
+
const rasterCanvas = this.ensureRasterImageCanvas(cached);
|
|
7336
|
+
this.positionRasterImageCanvas(rasterCanvas, target.contentRect);
|
|
7337
|
+
if (rasterCanvas.itemHref !== null && rasterCanvas.itemHref !== item.imageRasterHref) {
|
|
7338
|
+
this.clearRasterImageCanvasBitmap(rasterCanvas);
|
|
7339
|
+
}
|
|
7340
|
+
if (!shouldRedrawRasterImageCanvas({
|
|
7341
|
+
currentSourceKey: rasterCanvas.sourceKey,
|
|
7342
|
+
currentWidth: rasterCanvas.width,
|
|
7343
|
+
currentHeight: rasterCanvas.height,
|
|
7344
|
+
nextSourceKey: target.sourceKey,
|
|
7345
|
+
nextWidth: target.targetSize.width,
|
|
7346
|
+
nextHeight: target.targetSize.height,
|
|
7347
|
+
upscaleRedrawRatio: options.upscaleRedrawRatio
|
|
7348
|
+
})) {
|
|
7349
|
+
return;
|
|
7350
|
+
}
|
|
7351
|
+
const request = {
|
|
7352
|
+
itemHref: item.imageRasterHref,
|
|
7353
|
+
target
|
|
7354
|
+
};
|
|
7355
|
+
if (rasterCanvas.abortController) {
|
|
7356
|
+
if (rasterCanvas.loadingItemHref !== item.imageRasterHref) {
|
|
7357
|
+
rasterCanvas.abortController.abort();
|
|
7358
|
+
rasterCanvas.abortController = null;
|
|
7359
|
+
rasterCanvas.loadingItemHref = null;
|
|
7360
|
+
rasterCanvas.loadingSourceKey = null;
|
|
7361
|
+
rasterCanvas.loadingWidth = 0;
|
|
7362
|
+
rasterCanvas.loadingHeight = 0;
|
|
7363
|
+
rasterCanvas.queuedTarget = null;
|
|
7364
|
+
this.drawRasterImageCanvas(rasterCanvas, request);
|
|
7365
|
+
return;
|
|
7366
|
+
}
|
|
7367
|
+
if (rasterCanvas.loadingSourceKey === target.sourceKey && rasterCanvas.loadingWidth === target.targetSize.width && rasterCanvas.loadingHeight === target.targetSize.height) {
|
|
7368
|
+
return;
|
|
7369
|
+
}
|
|
7370
|
+
if (shouldRedrawRasterImageCanvas({
|
|
7371
|
+
currentSourceKey: rasterCanvas.loadingSourceKey,
|
|
7372
|
+
currentWidth: rasterCanvas.loadingWidth,
|
|
7373
|
+
currentHeight: rasterCanvas.loadingHeight,
|
|
7374
|
+
nextSourceKey: target.sourceKey,
|
|
7375
|
+
nextWidth: target.targetSize.width,
|
|
7376
|
+
nextHeight: target.targetSize.height,
|
|
7377
|
+
upscaleRedrawRatio: options.upscaleRedrawRatio
|
|
7378
|
+
})) {
|
|
7379
|
+
rasterCanvas.queuedTarget = request;
|
|
7380
|
+
}
|
|
7381
|
+
return;
|
|
7382
|
+
}
|
|
7383
|
+
this.drawRasterImageCanvas(rasterCanvas, request);
|
|
7384
|
+
}
|
|
7385
|
+
ensureRasterImageCanvas(cached) {
|
|
7386
|
+
if (cached.rasterCanvas) {
|
|
7387
|
+
if (!cached.rasterCanvas.foreignObject.isConnected) {
|
|
7388
|
+
cached.g.appendChild(cached.rasterCanvas.foreignObject);
|
|
7389
|
+
}
|
|
7390
|
+
return cached.rasterCanvas;
|
|
7391
|
+
}
|
|
7392
|
+
const foreignObject = document.createElementNS(
|
|
7393
|
+
"http://www.w3.org/2000/svg",
|
|
7394
|
+
"foreignObject"
|
|
7395
|
+
);
|
|
7396
|
+
foreignObject.setAttribute("data-canvu-raster-canvas", "true");
|
|
7397
|
+
foreignObject.style.pointerEvents = "none";
|
|
7398
|
+
const canvas = document.createElement("canvas");
|
|
7399
|
+
canvas.width = 1;
|
|
7400
|
+
canvas.height = 1;
|
|
7401
|
+
canvas.style.display = "block";
|
|
7402
|
+
canvas.style.width = "100%";
|
|
7403
|
+
canvas.style.height = "100%";
|
|
7404
|
+
foreignObject.appendChild(canvas);
|
|
7405
|
+
cached.g.appendChild(foreignObject);
|
|
7406
|
+
cached.rasterCanvas = {
|
|
7407
|
+
foreignObject,
|
|
7408
|
+
canvas,
|
|
7409
|
+
itemHref: null,
|
|
7410
|
+
sourceKey: null,
|
|
7411
|
+
width: 0,
|
|
7412
|
+
height: 0,
|
|
7413
|
+
loadSequence: 0,
|
|
7414
|
+
abortController: null,
|
|
7415
|
+
loadingItemHref: null,
|
|
7416
|
+
loadingSourceKey: null,
|
|
7417
|
+
loadingWidth: 0,
|
|
7418
|
+
loadingHeight: 0,
|
|
7419
|
+
queuedTarget: null
|
|
7420
|
+
};
|
|
7421
|
+
return cached.rasterCanvas;
|
|
7422
|
+
}
|
|
7423
|
+
positionRasterImageCanvas(rasterCanvas, contentRect) {
|
|
7424
|
+
rasterCanvas.foreignObject.setAttribute("x", String(contentRect.x));
|
|
7425
|
+
rasterCanvas.foreignObject.setAttribute("y", String(contentRect.y));
|
|
7426
|
+
rasterCanvas.foreignObject.setAttribute("width", String(contentRect.width));
|
|
7427
|
+
rasterCanvas.foreignObject.setAttribute("height", String(contentRect.height));
|
|
7428
|
+
}
|
|
7429
|
+
drawRasterImageCanvas(rasterCanvas, request) {
|
|
7430
|
+
const { target } = request;
|
|
7431
|
+
const width = Math.max(1, Math.round(target.targetSize.width));
|
|
7432
|
+
const height = Math.max(1, Math.round(target.targetSize.height));
|
|
7433
|
+
const sequence = rasterCanvas.loadSequence + 1;
|
|
7434
|
+
rasterCanvas.loadSequence = sequence;
|
|
7435
|
+
rasterCanvas.abortController?.abort();
|
|
7436
|
+
const abortController = new AbortController();
|
|
7437
|
+
rasterCanvas.abortController = abortController;
|
|
7438
|
+
rasterCanvas.loadingItemHref = request.itemHref;
|
|
7439
|
+
rasterCanvas.loadingSourceKey = target.sourceKey;
|
|
7440
|
+
rasterCanvas.loadingWidth = width;
|
|
7441
|
+
rasterCanvas.loadingHeight = height;
|
|
7442
|
+
rasterCanvas.queuedTarget = null;
|
|
7443
|
+
decodeRasterImage(target.href, width, height, abortController.signal).then((decoded) => {
|
|
7444
|
+
if (abortController.signal.aborted || rasterCanvas.loadSequence !== sequence) {
|
|
7445
|
+
decoded.close();
|
|
7446
|
+
return;
|
|
7447
|
+
}
|
|
7448
|
+
const context = rasterCanvas.canvas.getContext("2d");
|
|
7449
|
+
if (!context) {
|
|
7450
|
+
decoded.close();
|
|
7451
|
+
rasterCanvas.abortController = null;
|
|
7452
|
+
rasterCanvas.loadingItemHref = null;
|
|
7453
|
+
rasterCanvas.loadingSourceKey = null;
|
|
7454
|
+
rasterCanvas.loadingWidth = 0;
|
|
7455
|
+
rasterCanvas.loadingHeight = 0;
|
|
7456
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
7457
|
+
return;
|
|
7458
|
+
}
|
|
7459
|
+
rasterCanvas.canvas.width = decoded.width;
|
|
7460
|
+
rasterCanvas.canvas.height = decoded.height;
|
|
7461
|
+
context.clearRect(0, 0, decoded.width, decoded.height);
|
|
7462
|
+
decoded.draw(context);
|
|
7463
|
+
decoded.close();
|
|
7464
|
+
rasterCanvas.itemHref = request.itemHref;
|
|
7465
|
+
rasterCanvas.sourceKey = target.sourceKey;
|
|
7466
|
+
rasterCanvas.width = decoded.width;
|
|
7467
|
+
rasterCanvas.height = decoded.height;
|
|
7468
|
+
rasterCanvas.abortController = null;
|
|
7469
|
+
rasterCanvas.loadingItemHref = null;
|
|
7470
|
+
rasterCanvas.loadingSourceKey = null;
|
|
7471
|
+
rasterCanvas.loadingWidth = 0;
|
|
7472
|
+
rasterCanvas.loadingHeight = 0;
|
|
7473
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
7474
|
+
}).catch((error) => {
|
|
7475
|
+
if (abortController.signal.aborted) return;
|
|
7476
|
+
if (error instanceof Error && error.name === "AbortError") return;
|
|
7477
|
+
if (rasterCanvas.loadSequence === sequence) {
|
|
7478
|
+
rasterCanvas.abortController = null;
|
|
7479
|
+
rasterCanvas.loadingItemHref = null;
|
|
7480
|
+
rasterCanvas.loadingSourceKey = null;
|
|
7481
|
+
rasterCanvas.loadingWidth = 0;
|
|
7482
|
+
rasterCanvas.loadingHeight = 0;
|
|
7483
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
7484
|
+
}
|
|
7485
|
+
});
|
|
7486
|
+
}
|
|
7487
|
+
drawQueuedRasterImageCanvasTarget(rasterCanvas) {
|
|
7488
|
+
const queuedTarget = rasterCanvas.queuedTarget;
|
|
7489
|
+
if (!queuedTarget) return;
|
|
7490
|
+
rasterCanvas.queuedTarget = null;
|
|
7491
|
+
if (!shouldRedrawRasterImageCanvas({
|
|
7492
|
+
currentSourceKey: rasterCanvas.sourceKey,
|
|
7493
|
+
currentWidth: rasterCanvas.width,
|
|
7494
|
+
currentHeight: rasterCanvas.height,
|
|
7495
|
+
nextSourceKey: queuedTarget.target.sourceKey,
|
|
7496
|
+
nextWidth: queuedTarget.target.targetSize.width,
|
|
7497
|
+
nextHeight: queuedTarget.target.targetSize.height,
|
|
7498
|
+
upscaleRedrawRatio: this.rasterImageCanvasRendering?.upscaleRedrawRatio ?? 1
|
|
7499
|
+
})) {
|
|
7500
|
+
return;
|
|
7501
|
+
}
|
|
7502
|
+
this.drawRasterImageCanvas(rasterCanvas, queuedTarget);
|
|
7503
|
+
}
|
|
7504
|
+
clearRasterImageCanvasBitmap(rasterCanvas) {
|
|
7505
|
+
const context = rasterCanvas.canvas.getContext("2d");
|
|
7506
|
+
context?.clearRect(0, 0, rasterCanvas.canvas.width, rasterCanvas.canvas.height);
|
|
7507
|
+
rasterCanvas.canvas.width = 1;
|
|
7508
|
+
rasterCanvas.canvas.height = 1;
|
|
7509
|
+
rasterCanvas.itemHref = null;
|
|
7510
|
+
rasterCanvas.sourceKey = null;
|
|
7511
|
+
rasterCanvas.width = 0;
|
|
7512
|
+
rasterCanvas.height = 0;
|
|
7513
|
+
}
|
|
7514
|
+
releaseRasterImageCanvas(cached) {
|
|
7515
|
+
const rasterCanvas = cached.rasterCanvas;
|
|
7516
|
+
if (!rasterCanvas) return;
|
|
7517
|
+
rasterCanvas.abortController?.abort();
|
|
7518
|
+
rasterCanvas.loadSequence += 1;
|
|
7519
|
+
rasterCanvas.queuedTarget = null;
|
|
7520
|
+
rasterCanvas.foreignObject.remove();
|
|
7521
|
+
cached.rasterCanvas = void 0;
|
|
7522
|
+
}
|
|
7059
7523
|
applyInteractionAttributes(g, itemId) {
|
|
7060
7524
|
g.setAttribute(
|
|
7061
7525
|
"data-canvu-selected",
|
|
@@ -7068,6 +7532,9 @@ var SvgVectorRenderer = class {
|
|
|
7068
7532
|
}
|
|
7069
7533
|
destroy() {
|
|
7070
7534
|
this.resizeObserver.disconnect();
|
|
7535
|
+
for (const cached of this.itemNodeCache.values()) {
|
|
7536
|
+
this.releaseRasterImageCanvas(cached);
|
|
7537
|
+
}
|
|
7071
7538
|
this.itemNodeCache.clear();
|
|
7072
7539
|
this.liveOverlay = null;
|
|
7073
7540
|
this.svg.remove();
|
|
@@ -8357,6 +8824,7 @@ var VectorViewport = forwardRef(
|
|
|
8357
8824
|
customPlacement: consumerCustomPlacement,
|
|
8358
8825
|
customPlacements: consumerCustomPlacements,
|
|
8359
8826
|
assetStore,
|
|
8827
|
+
imageCanvasRendering,
|
|
8360
8828
|
toolLocked = false,
|
|
8361
8829
|
autoResetToolTo = "select",
|
|
8362
8830
|
onToolChangeRequest,
|
|
@@ -8563,6 +9031,8 @@ var VectorViewport = forwardRef(
|
|
|
8563
9031
|
onActivateLinkRef.current = onActivateLink;
|
|
8564
9032
|
const assetStoreRef = useRef(assetStore);
|
|
8565
9033
|
assetStoreRef.current = assetStore;
|
|
9034
|
+
const imageCanvasRenderingRef = useRef(imageCanvasRendering);
|
|
9035
|
+
imageCanvasRenderingRef.current = imageCanvasRendering;
|
|
8566
9036
|
const customPlacementRef = useRef(customPlacement);
|
|
8567
9037
|
customPlacementRef.current = customPlacement;
|
|
8568
9038
|
const allCustomPlacementsRef = useRef(allCustomPlacements);
|
|
@@ -9183,7 +9653,8 @@ var VectorViewport = forwardRef(
|
|
|
9183
9653
|
container: el,
|
|
9184
9654
|
scene,
|
|
9185
9655
|
camera,
|
|
9186
|
-
pointerEventsNone: interactiveRef.current
|
|
9656
|
+
pointerEventsNone: interactiveRef.current,
|
|
9657
|
+
rasterImageCanvas: imageCanvasRenderingRef.current
|
|
9187
9658
|
});
|
|
9188
9659
|
rendererRef.current = renderer;
|
|
9189
9660
|
renderer.setInteractionState({
|
|
@@ -9235,6 +9706,9 @@ var VectorViewport = forwardRef(
|
|
|
9235
9706
|
hoveredItemId: hoveredItemIdRef.current
|
|
9236
9707
|
});
|
|
9237
9708
|
}, [effectiveSelectedIds]);
|
|
9709
|
+
useEffect(() => {
|
|
9710
|
+
rendererRef.current?.setRasterImageCanvasRendering(imageCanvasRendering);
|
|
9711
|
+
}, [imageCanvasRendering]);
|
|
9238
9712
|
useEffect(() => {
|
|
9239
9713
|
const r = rendererRef.current;
|
|
9240
9714
|
if (!r) return;
|
|
@@ -9774,15 +10248,26 @@ var VectorViewport = forwardRef(
|
|
|
9774
10248
|
if (!cam) return;
|
|
9775
10249
|
const { worldX, worldY } = screenToWorld(e.clientX, e.clientY);
|
|
9776
10250
|
const lineHitWorld = 10 / cam.zoom;
|
|
10251
|
+
const cur = effectiveSelectedIdsRef.current;
|
|
9777
10252
|
const hit = hitTestWorldPoint(resolvedItemsRef.current, worldX, worldY, {
|
|
9778
10253
|
lineHitWorld,
|
|
9779
10254
|
ignoreLocked: true
|
|
9780
10255
|
});
|
|
9781
10256
|
if (!hit) {
|
|
10257
|
+
const selectedUnlockedItems = cur.map((id) => resolvedItemsRef.current.find((item) => item.id === id)).filter((item) => item != null && !item.locked);
|
|
10258
|
+
if (selectedUnlockedItems.some(
|
|
10259
|
+
(item) => pointInSelectedItemBounds(item, worldX, worldY)
|
|
10260
|
+
)) {
|
|
10261
|
+
setContextMenuState({
|
|
10262
|
+
x: e.clientX,
|
|
10263
|
+
y: e.clientY,
|
|
10264
|
+
itemIds: [...cur]
|
|
10265
|
+
});
|
|
10266
|
+
return;
|
|
10267
|
+
}
|
|
9782
10268
|
setContextMenuState(null);
|
|
9783
10269
|
return;
|
|
9784
10270
|
}
|
|
9785
|
-
const cur = effectiveSelectedIdsRef.current;
|
|
9786
10271
|
let nextIds;
|
|
9787
10272
|
if (!cur.includes(hit.id)) {
|
|
9788
10273
|
nextIds = e.shiftKey ? [...cur, hit.id] : [hit.id];
|