canvu-react 0.4.67 → 0.4.69
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-D2xaUoAT.d.cts} +1 -1
- package/dist/{asset-hydration-BSjiek7Q.d.ts → asset-hydration-D9eThWse.d.ts} +1 -1
- package/dist/chatbot.d.cts +2 -2
- package/dist/chatbot.d.ts +2 -2
- package/dist/index.cjs +501 -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 +501 -0
- package/dist/index.js.map +1 -1
- package/dist/raster-image-canvas-CCOmB4NY.d.ts +219 -0
- package/dist/raster-image-canvas-nK9kM9UJ.d.cts +219 -0
- package/dist/react.cjs +510 -1
- 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 +510 -1
- 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-CMuEaiM7.d.ts} +12 -1
- package/dist/{types-D5d-3dvz.d.cts → types-D402X18k.d.cts} +12 -1
- package/package.json +1 -1
- package/dist/asset-store-35ysK28r.d.cts +0 -113
- package/dist/asset-store-D_FjW_CN.d.ts +0 -113
package/dist/index.d.cts
CHANGED
|
@@ -2,9 +2,9 @@ import { C as Camera2D } from './shape-builders-DzhCOuzo.cjs';
|
|
|
2
2
|
export { a as Camera2DOptions, D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, b as applyStrokeToItem, c as buildArchitecturalCloudPathD, d as buildArchitecturalCloudSvg, e as buildArrowSvg, f as buildDrawDotSvg, g as buildEllipseSvg, h as buildFreehandPathSvg, i as buildLineSvg, j as buildRectSvg, k as computeFreehandSvgPayload, l as createArchitecturalCloudItem, m as createDrawDotItem, n as createEllipseItem, o as createFreehandStrokeItem, p as createImageFromVectorTrace, q as createImageItem, r as createLineItem, s as createRectangleItem, t as createShapeId, u as createTextItem, v as lineEndpointsToLocal, w as rebuildItemSvg, x as resolveStrokeStyle } from './shape-builders-DzhCOuzo.cjs';
|
|
3
3
|
import { V as VectorSceneItem, A as ArrowEndpointBinding, C as CustomShapeResizeHandles, R as Rect } from './types-fJNwEnHf.cjs';
|
|
4
4
|
export { a as ArrowBindings, b as ResizeHandleId, c as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-fJNwEnHf.cjs';
|
|
5
|
-
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-
|
|
5
|
+
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-D2xaUoAT.cjs';
|
|
6
|
+
import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-nK9kM9UJ.cjs';
|
|
6
7
|
export { C as CanvuLinkData, D as DEFAULT_LINK_CARD_SIZE, L as LINK_PLUGIN_KEY, b as buildLinkCardSvg, c as createLinkItem, g as getLinkData, i as isLinkItem } from './link-item-BMV3VUCr.cjs';
|
|
7
|
-
import './asset-store-35ysK28r.cjs';
|
|
8
8
|
|
|
9
9
|
type EncodeCanvasToBlobOptions = {
|
|
10
10
|
mimeType?: string;
|
|
@@ -180,6 +180,7 @@ type SvgVectorRendererOptions = {
|
|
|
180
180
|
* (interactive selection / resize / placement).
|
|
181
181
|
*/
|
|
182
182
|
pointerEventsNone?: boolean;
|
|
183
|
+
rasterImageCanvas?: RasterImageCanvasRenderingOptions | null;
|
|
183
184
|
};
|
|
184
185
|
type SvgVectorRendererInteractionState = {
|
|
185
186
|
selectedIds?: readonly string[];
|
|
@@ -204,6 +205,7 @@ declare class SvgVectorRenderer {
|
|
|
204
205
|
private hoveredItemId;
|
|
205
206
|
private liveOverlay;
|
|
206
207
|
private readonly resizeObserver;
|
|
208
|
+
private rasterImageCanvasRendering;
|
|
207
209
|
constructor(options: SvgVectorRendererOptions);
|
|
208
210
|
/**
|
|
209
211
|
* Updates interaction attributes on item groups for CSS hooks.
|
|
@@ -213,6 +215,7 @@ declare class SvgVectorRenderer {
|
|
|
213
215
|
* pointer events.
|
|
214
216
|
*/
|
|
215
217
|
setInteractionState(state: SvgVectorRendererInteractionState): void;
|
|
218
|
+
setRasterImageCanvasRendering(options: RasterImageCanvasRenderingOptions | null | undefined): void;
|
|
216
219
|
/**
|
|
217
220
|
* Reads container size, culls items, and updates the SVG (incrementally when possible).
|
|
218
221
|
*/
|
|
@@ -228,6 +231,13 @@ declare class SvgVectorRenderer {
|
|
|
228
231
|
renderLiveItem(item: VectorSceneItem | null): void;
|
|
229
232
|
private keepLiveOverlayOnTop;
|
|
230
233
|
private syncVisibleItems;
|
|
234
|
+
private syncRasterImageCanvas;
|
|
235
|
+
private ensureRasterImageCanvas;
|
|
236
|
+
private positionRasterImageCanvas;
|
|
237
|
+
private drawRasterImageCanvas;
|
|
238
|
+
private drawQueuedRasterImageCanvasTarget;
|
|
239
|
+
private clearRasterImageCanvasBitmap;
|
|
240
|
+
private releaseRasterImageCanvas;
|
|
231
241
|
private applyInteractionAttributes;
|
|
232
242
|
destroy(): void;
|
|
233
243
|
/** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { C as Camera2D } from './shape-builders-xG3A66sv.js';
|
|
|
2
2
|
export { a as Camera2DOptions, D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, b as applyStrokeToItem, c as buildArchitecturalCloudPathD, d as buildArchitecturalCloudSvg, e as buildArrowSvg, f as buildDrawDotSvg, g as buildEllipseSvg, h as buildFreehandPathSvg, i as buildLineSvg, j as buildRectSvg, k as computeFreehandSvgPayload, l as createArchitecturalCloudItem, m as createDrawDotItem, n as createEllipseItem, o as createFreehandStrokeItem, p as createImageFromVectorTrace, q as createImageItem, r as createLineItem, s as createRectangleItem, t as createShapeId, u as createTextItem, v as lineEndpointsToLocal, w as rebuildItemSvg, x as resolveStrokeStyle } from './shape-builders-xG3A66sv.js';
|
|
3
3
|
import { V as VectorSceneItem, A as ArrowEndpointBinding, C as CustomShapeResizeHandles, R as Rect } from './types-fJNwEnHf.js';
|
|
4
4
|
export { a as ArrowBindings, b as ResizeHandleId, c as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-fJNwEnHf.js';
|
|
5
|
-
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-
|
|
5
|
+
export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-D9eThWse.js';
|
|
6
|
+
import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-CCOmB4NY.js';
|
|
6
7
|
export { C as CanvuLinkData, D as DEFAULT_LINK_CARD_SIZE, L as LINK_PLUGIN_KEY, b as buildLinkCardSvg, c as createLinkItem, g as getLinkData, i as isLinkItem } from './link-item-COoNNvCu.js';
|
|
7
|
-
import './asset-store-D_FjW_CN.js';
|
|
8
8
|
|
|
9
9
|
type EncodeCanvasToBlobOptions = {
|
|
10
10
|
mimeType?: string;
|
|
@@ -180,6 +180,7 @@ type SvgVectorRendererOptions = {
|
|
|
180
180
|
* (interactive selection / resize / placement).
|
|
181
181
|
*/
|
|
182
182
|
pointerEventsNone?: boolean;
|
|
183
|
+
rasterImageCanvas?: RasterImageCanvasRenderingOptions | null;
|
|
183
184
|
};
|
|
184
185
|
type SvgVectorRendererInteractionState = {
|
|
185
186
|
selectedIds?: readonly string[];
|
|
@@ -204,6 +205,7 @@ declare class SvgVectorRenderer {
|
|
|
204
205
|
private hoveredItemId;
|
|
205
206
|
private liveOverlay;
|
|
206
207
|
private readonly resizeObserver;
|
|
208
|
+
private rasterImageCanvasRendering;
|
|
207
209
|
constructor(options: SvgVectorRendererOptions);
|
|
208
210
|
/**
|
|
209
211
|
* Updates interaction attributes on item groups for CSS hooks.
|
|
@@ -213,6 +215,7 @@ declare class SvgVectorRenderer {
|
|
|
213
215
|
* pointer events.
|
|
214
216
|
*/
|
|
215
217
|
setInteractionState(state: SvgVectorRendererInteractionState): void;
|
|
218
|
+
setRasterImageCanvasRendering(options: RasterImageCanvasRenderingOptions | null | undefined): void;
|
|
216
219
|
/**
|
|
217
220
|
* Reads container size, culls items, and updates the SVG (incrementally when possible).
|
|
218
221
|
*/
|
|
@@ -228,6 +231,13 @@ declare class SvgVectorRenderer {
|
|
|
228
231
|
renderLiveItem(item: VectorSceneItem | null): void;
|
|
229
232
|
private keepLiveOverlayOnTop;
|
|
230
233
|
private syncVisibleItems;
|
|
234
|
+
private syncRasterImageCanvas;
|
|
235
|
+
private ensureRasterImageCanvas;
|
|
236
|
+
private positionRasterImageCanvas;
|
|
237
|
+
private drawRasterImageCanvas;
|
|
238
|
+
private drawQueuedRasterImageCanvasTarget;
|
|
239
|
+
private clearRasterImageCanvasBitmap;
|
|
240
|
+
private releaseRasterImageCanvas;
|
|
231
241
|
private applyInteractionAttributes;
|
|
232
242
|
destroy(): void;
|
|
233
243
|
/** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */
|
package/dist/index.js
CHANGED
|
@@ -2570,6 +2570,176 @@ function cullItemsByViewport(items, visibleWorld) {
|
|
|
2570
2570
|
return cullItemsByViewportSpatial(items, visibleWorld, SPATIAL_CELL_SIZE);
|
|
2571
2571
|
}
|
|
2572
2572
|
|
|
2573
|
+
// src/renderer/raster-image-canvas.ts
|
|
2574
|
+
var DEFAULT_PIXEL_HEADROOM = 1.5;
|
|
2575
|
+
var DEFAULT_MAX_PIXEL_COUNT = 12e6;
|
|
2576
|
+
var DEFAULT_MAX_DIMENSION = 4096;
|
|
2577
|
+
var DEFAULT_UPSCALE_REDRAW_RATIO = 1.15;
|
|
2578
|
+
function resolveRasterImageCanvasRenderingOptions(options) {
|
|
2579
|
+
if (!options) return null;
|
|
2580
|
+
const fallbackDevicePixelRatio = typeof window === "undefined" ? 1 : window.devicePixelRatio;
|
|
2581
|
+
return {
|
|
2582
|
+
resolveSourceSize: options.resolveSourceSize,
|
|
2583
|
+
resolveRenderTarget: options.resolveRenderTarget,
|
|
2584
|
+
devicePixelRatio: toPositiveFiniteNumber(
|
|
2585
|
+
options.devicePixelRatio,
|
|
2586
|
+
fallbackDevicePixelRatio
|
|
2587
|
+
),
|
|
2588
|
+
pixelHeadroom: toPositiveFiniteNumber(
|
|
2589
|
+
options.pixelHeadroom,
|
|
2590
|
+
DEFAULT_PIXEL_HEADROOM
|
|
2591
|
+
),
|
|
2592
|
+
maxPixelCount: toPositiveFiniteNumber(
|
|
2593
|
+
options.maxPixelCount,
|
|
2594
|
+
DEFAULT_MAX_PIXEL_COUNT
|
|
2595
|
+
),
|
|
2596
|
+
maxDimension: toPositiveFiniteNumber(
|
|
2597
|
+
options.maxDimension,
|
|
2598
|
+
DEFAULT_MAX_DIMENSION
|
|
2599
|
+
),
|
|
2600
|
+
upscaleRedrawRatio: toPositiveFiniteNumber(
|
|
2601
|
+
options.upscaleRedrawRatio,
|
|
2602
|
+
DEFAULT_UPSCALE_REDRAW_RATIO
|
|
2603
|
+
)
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
function getRasterImageContentRect(item) {
|
|
2607
|
+
if (item.toolKind !== "image" || !item.imageIntrinsicSize) return null;
|
|
2608
|
+
const bounds = normalizeRect(item.bounds);
|
|
2609
|
+
const intrinsicWidth = Math.max(1e-6, item.imageIntrinsicSize.width);
|
|
2610
|
+
const intrinsicHeight = Math.max(1e-6, item.imageIntrinsicSize.height);
|
|
2611
|
+
const boundsAspectRatio = bounds.width / Math.max(1e-9, bounds.height);
|
|
2612
|
+
const imageAspectRatio = intrinsicWidth / intrinsicHeight;
|
|
2613
|
+
if (Math.abs(boundsAspectRatio - imageAspectRatio) < 1e-3) {
|
|
2614
|
+
return { x: 0, y: 0, width: bounds.width, height: bounds.height };
|
|
2615
|
+
}
|
|
2616
|
+
if (boundsAspectRatio > imageAspectRatio) {
|
|
2617
|
+
const height2 = bounds.height;
|
|
2618
|
+
const width2 = height2 * imageAspectRatio;
|
|
2619
|
+
return { x: (bounds.width - width2) / 2, y: 0, width: width2, height: height2 };
|
|
2620
|
+
}
|
|
2621
|
+
const width = bounds.width;
|
|
2622
|
+
const height = width / imageAspectRatio;
|
|
2623
|
+
return { x: 0, y: (bounds.height - height) / 2, width, height };
|
|
2624
|
+
}
|
|
2625
|
+
function resolveRasterImageCanvasSourceSize({
|
|
2626
|
+
item,
|
|
2627
|
+
href,
|
|
2628
|
+
intrinsicSize,
|
|
2629
|
+
contentRect,
|
|
2630
|
+
viewportSize,
|
|
2631
|
+
cameraZoom,
|
|
2632
|
+
options
|
|
2633
|
+
}) {
|
|
2634
|
+
const resolved = options.resolveSourceSize?.({
|
|
2635
|
+
item,
|
|
2636
|
+
href,
|
|
2637
|
+
intrinsicSize,
|
|
2638
|
+
contentRect,
|
|
2639
|
+
viewportSize,
|
|
2640
|
+
cameraZoom,
|
|
2641
|
+
devicePixelRatio: options.devicePixelRatio
|
|
2642
|
+
});
|
|
2643
|
+
const width = toPositiveFiniteNumber(resolved?.width, intrinsicSize.width);
|
|
2644
|
+
const height = toPositiveFiniteNumber(resolved?.height, intrinsicSize.height);
|
|
2645
|
+
return { width, height };
|
|
2646
|
+
}
|
|
2647
|
+
function getRasterImageCanvasTargetSize({
|
|
2648
|
+
intrinsicSize,
|
|
2649
|
+
contentRect,
|
|
2650
|
+
cameraZoom,
|
|
2651
|
+
devicePixelRatio,
|
|
2652
|
+
pixelHeadroom,
|
|
2653
|
+
maxPixelCount,
|
|
2654
|
+
maxDimension
|
|
2655
|
+
}) {
|
|
2656
|
+
const intrinsicWidth = Math.max(1, Math.round(intrinsicSize.width));
|
|
2657
|
+
const intrinsicHeight = Math.max(1, Math.round(intrinsicSize.height));
|
|
2658
|
+
const targetCssWidth = Math.max(1, contentRect.width * cameraZoom);
|
|
2659
|
+
const targetCssHeight = Math.max(1, contentRect.height * cameraZoom);
|
|
2660
|
+
const desiredWidth = targetCssWidth * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
|
|
2661
|
+
const desiredHeight = targetCssHeight * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
|
|
2662
|
+
const dimensionScale = Math.min(
|
|
2663
|
+
1,
|
|
2664
|
+
toPositiveFiniteNumber(maxDimension, intrinsicWidth) / Math.max(intrinsicWidth, intrinsicHeight)
|
|
2665
|
+
);
|
|
2666
|
+
const pixelScale = Math.min(
|
|
2667
|
+
1,
|
|
2668
|
+
Math.sqrt(
|
|
2669
|
+
toPositiveFiniteNumber(maxPixelCount, intrinsicWidth * intrinsicHeight) / (intrinsicWidth * intrinsicHeight)
|
|
2670
|
+
)
|
|
2671
|
+
);
|
|
2672
|
+
const viewportScale = Math.min(
|
|
2673
|
+
1,
|
|
2674
|
+
desiredWidth / intrinsicWidth,
|
|
2675
|
+
desiredHeight / intrinsicHeight
|
|
2676
|
+
);
|
|
2677
|
+
const scale = Math.min(dimensionScale, pixelScale, viewportScale);
|
|
2678
|
+
const width = Math.max(1, Math.round(intrinsicWidth * scale));
|
|
2679
|
+
const height = Math.max(1, Math.round(width * (intrinsicHeight / intrinsicWidth)));
|
|
2680
|
+
return { width, height };
|
|
2681
|
+
}
|
|
2682
|
+
function resolveRasterImageCanvasRenderTarget({
|
|
2683
|
+
item,
|
|
2684
|
+
href,
|
|
2685
|
+
intrinsicSize,
|
|
2686
|
+
sourceSize,
|
|
2687
|
+
contentRect,
|
|
2688
|
+
targetSize,
|
|
2689
|
+
viewportSize,
|
|
2690
|
+
cameraZoom,
|
|
2691
|
+
options
|
|
2692
|
+
}) {
|
|
2693
|
+
const request = {
|
|
2694
|
+
item,
|
|
2695
|
+
href,
|
|
2696
|
+
intrinsicSize,
|
|
2697
|
+
sourceSize,
|
|
2698
|
+
contentRect,
|
|
2699
|
+
targetSize,
|
|
2700
|
+
viewportSize,
|
|
2701
|
+
cameraZoom,
|
|
2702
|
+
devicePixelRatio: options.devicePixelRatio
|
|
2703
|
+
};
|
|
2704
|
+
const resolved = options.resolveRenderTarget?.(request);
|
|
2705
|
+
if (typeof resolved === "string") {
|
|
2706
|
+
return { href: resolved, sourceKey: resolved, targetSize, contentRect };
|
|
2707
|
+
}
|
|
2708
|
+
if (resolved?.href) {
|
|
2709
|
+
return {
|
|
2710
|
+
href: resolved.href,
|
|
2711
|
+
sourceKey: resolved.sourceKey ?? resolved.href,
|
|
2712
|
+
targetSize,
|
|
2713
|
+
contentRect
|
|
2714
|
+
};
|
|
2715
|
+
}
|
|
2716
|
+
return { href, sourceKey: href, targetSize, contentRect };
|
|
2717
|
+
}
|
|
2718
|
+
function shouldRedrawRasterImageCanvas({
|
|
2719
|
+
currentSourceKey,
|
|
2720
|
+
currentWidth,
|
|
2721
|
+
currentHeight,
|
|
2722
|
+
nextSourceKey,
|
|
2723
|
+
nextWidth,
|
|
2724
|
+
nextHeight,
|
|
2725
|
+
upscaleRedrawRatio
|
|
2726
|
+
}) {
|
|
2727
|
+
const safeCurrentWidth = Math.max(0, Math.round(currentWidth));
|
|
2728
|
+
const safeCurrentHeight = Math.max(0, Math.round(currentHeight));
|
|
2729
|
+
const safeNextWidth = Math.max(1, Math.round(nextWidth));
|
|
2730
|
+
const safeNextHeight = Math.max(1, Math.round(nextHeight));
|
|
2731
|
+
if (!currentSourceKey || safeCurrentWidth <= 1 || safeCurrentHeight <= 1) {
|
|
2732
|
+
return true;
|
|
2733
|
+
}
|
|
2734
|
+
if (currentSourceKey !== nextSourceKey && safeCurrentWidth === safeNextWidth && safeCurrentHeight === safeNextHeight) {
|
|
2735
|
+
return true;
|
|
2736
|
+
}
|
|
2737
|
+
return safeNextWidth > safeCurrentWidth * upscaleRedrawRatio || safeNextHeight > safeCurrentHeight * upscaleRedrawRatio;
|
|
2738
|
+
}
|
|
2739
|
+
function toPositiveFiniteNumber(value, fallback) {
|
|
2740
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2573
2743
|
// src/renderer/svg-vector-renderer.ts
|
|
2574
2744
|
function formatCameraTransform(camera) {
|
|
2575
2745
|
const z = camera.zoom;
|
|
@@ -2594,6 +2764,87 @@ function itemClassName(item) {
|
|
|
2594
2764
|
}
|
|
2595
2765
|
return classes.join(" ");
|
|
2596
2766
|
}
|
|
2767
|
+
async function decodeRasterImage(href, width, height, signal) {
|
|
2768
|
+
if (typeof createImageBitmap === "function") {
|
|
2769
|
+
try {
|
|
2770
|
+
const response = await fetch(href, { signal, credentials: "same-origin" });
|
|
2771
|
+
if (!response.ok) {
|
|
2772
|
+
throw new Error(`Failed to fetch raster image: ${response.status}`);
|
|
2773
|
+
}
|
|
2774
|
+
const blob = await response.blob();
|
|
2775
|
+
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
2776
|
+
const bitmap = await createImageBitmap(blob, {
|
|
2777
|
+
resizeWidth: width,
|
|
2778
|
+
resizeHeight: height,
|
|
2779
|
+
resizeQuality: "high"
|
|
2780
|
+
});
|
|
2781
|
+
return {
|
|
2782
|
+
width: bitmap.width,
|
|
2783
|
+
height: bitmap.height,
|
|
2784
|
+
draw: (context) => {
|
|
2785
|
+
context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
|
|
2786
|
+
},
|
|
2787
|
+
close: () => bitmap.close()
|
|
2788
|
+
};
|
|
2789
|
+
} catch (error) {
|
|
2790
|
+
if (signal.aborted) throw error;
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
const image = await loadImageElement(href, signal);
|
|
2794
|
+
return {
|
|
2795
|
+
width,
|
|
2796
|
+
height,
|
|
2797
|
+
draw: (context) => {
|
|
2798
|
+
context.drawImage(image, 0, 0, width, height);
|
|
2799
|
+
},
|
|
2800
|
+
close: () => {
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
function loadImageElement(href, signal) {
|
|
2805
|
+
return new Promise((resolve, reject) => {
|
|
2806
|
+
if (signal.aborted) {
|
|
2807
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
const image = new Image();
|
|
2811
|
+
const cleanup = () => {
|
|
2812
|
+
signal.removeEventListener("abort", abort);
|
|
2813
|
+
image.onload = null;
|
|
2814
|
+
image.onerror = null;
|
|
2815
|
+
};
|
|
2816
|
+
const abort = () => {
|
|
2817
|
+
cleanup();
|
|
2818
|
+
image.removeAttribute("src");
|
|
2819
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
2820
|
+
};
|
|
2821
|
+
image.decoding = "async";
|
|
2822
|
+
image.onload = () => {
|
|
2823
|
+
const decodePromise = image.decode?.();
|
|
2824
|
+
if (!decodePromise) {
|
|
2825
|
+
cleanup();
|
|
2826
|
+
resolve(image);
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
decodePromise.then(
|
|
2830
|
+
() => {
|
|
2831
|
+
cleanup();
|
|
2832
|
+
resolve(image);
|
|
2833
|
+
},
|
|
2834
|
+
() => {
|
|
2835
|
+
cleanup();
|
|
2836
|
+
resolve(image);
|
|
2837
|
+
}
|
|
2838
|
+
);
|
|
2839
|
+
};
|
|
2840
|
+
image.onerror = () => {
|
|
2841
|
+
cleanup();
|
|
2842
|
+
reject(new Error("Failed to load raster image"));
|
|
2843
|
+
};
|
|
2844
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
2845
|
+
image.src = href;
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2597
2848
|
var SvgVectorRenderer = class {
|
|
2598
2849
|
container;
|
|
2599
2850
|
scene;
|
|
@@ -2605,10 +2856,14 @@ var SvgVectorRenderer = class {
|
|
|
2605
2856
|
hoveredItemId = null;
|
|
2606
2857
|
liveOverlay = null;
|
|
2607
2858
|
resizeObserver;
|
|
2859
|
+
rasterImageCanvasRendering;
|
|
2608
2860
|
constructor(options) {
|
|
2609
2861
|
this.container = options.container;
|
|
2610
2862
|
this.scene = options.scene;
|
|
2611
2863
|
this.camera = options.camera;
|
|
2864
|
+
this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(
|
|
2865
|
+
options.rasterImageCanvas
|
|
2866
|
+
);
|
|
2612
2867
|
this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
2613
2868
|
this.svg.setAttribute("width", "100%");
|
|
2614
2869
|
this.svg.setAttribute("height", "100%");
|
|
@@ -2637,6 +2892,15 @@ var SvgVectorRenderer = class {
|
|
|
2637
2892
|
this.applyInteractionAttributes(cached.g, id);
|
|
2638
2893
|
}
|
|
2639
2894
|
}
|
|
2895
|
+
setRasterImageCanvasRendering(options) {
|
|
2896
|
+
this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(options);
|
|
2897
|
+
if (!this.rasterImageCanvasRendering) {
|
|
2898
|
+
for (const cached of this.itemNodeCache.values()) {
|
|
2899
|
+
this.releaseRasterImageCanvas(cached);
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
this.render();
|
|
2903
|
+
}
|
|
2640
2904
|
/**
|
|
2641
2905
|
* Reads container size, culls items, and updates the SVG (incrementally when possible).
|
|
2642
2906
|
*/
|
|
@@ -2710,6 +2974,7 @@ var SvgVectorRenderer = class {
|
|
|
2710
2974
|
}
|
|
2711
2975
|
for (const [id, cached] of this.itemNodeCache) {
|
|
2712
2976
|
if (!visibleIds.has(id)) {
|
|
2977
|
+
this.releaseRasterImageCanvas(cached);
|
|
2713
2978
|
cached.g.remove();
|
|
2714
2979
|
}
|
|
2715
2980
|
}
|
|
@@ -2742,6 +3007,7 @@ var SvgVectorRenderer = class {
|
|
|
2742
3007
|
g.innerHTML = item.childrenSvg;
|
|
2743
3008
|
cached.lastChildrenSvg = item.childrenSvg;
|
|
2744
3009
|
}
|
|
3010
|
+
this.syncRasterImageCanvas(cached, item);
|
|
2745
3011
|
const expectedPosition = previousNode ? previousNode.nextSibling : this.rootG.firstChild;
|
|
2746
3012
|
if (expectedPosition !== g) {
|
|
2747
3013
|
this.rootG.insertBefore(g, expectedPosition);
|
|
@@ -2749,6 +3015,238 @@ var SvgVectorRenderer = class {
|
|
|
2749
3015
|
previousNode = g;
|
|
2750
3016
|
}
|
|
2751
3017
|
}
|
|
3018
|
+
syncRasterImageCanvas(cached, item) {
|
|
3019
|
+
const options = this.rasterImageCanvasRendering;
|
|
3020
|
+
if (!options || item.toolKind !== "image" || !item.imageRasterHref || !item.imageIntrinsicSize) {
|
|
3021
|
+
this.releaseRasterImageCanvas(cached);
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
const contentRect = getRasterImageContentRect(item);
|
|
3025
|
+
const viewportSize = {
|
|
3026
|
+
width: this.container.clientWidth,
|
|
3027
|
+
height: this.container.clientHeight
|
|
3028
|
+
};
|
|
3029
|
+
if (!contentRect || viewportSize.width <= 0 || viewportSize.height <= 0) {
|
|
3030
|
+
this.releaseRasterImageCanvas(cached);
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
3033
|
+
const sourceSize = resolveRasterImageCanvasSourceSize({
|
|
3034
|
+
item,
|
|
3035
|
+
href: item.imageRasterHref,
|
|
3036
|
+
intrinsicSize: item.imageIntrinsicSize,
|
|
3037
|
+
contentRect,
|
|
3038
|
+
viewportSize,
|
|
3039
|
+
cameraZoom: this.camera.zoom,
|
|
3040
|
+
options
|
|
3041
|
+
});
|
|
3042
|
+
const targetSize = getRasterImageCanvasTargetSize({
|
|
3043
|
+
intrinsicSize: sourceSize,
|
|
3044
|
+
contentRect,
|
|
3045
|
+
cameraZoom: this.camera.zoom,
|
|
3046
|
+
devicePixelRatio: options.devicePixelRatio,
|
|
3047
|
+
pixelHeadroom: options.pixelHeadroom,
|
|
3048
|
+
maxPixelCount: options.maxPixelCount,
|
|
3049
|
+
maxDimension: options.maxDimension
|
|
3050
|
+
});
|
|
3051
|
+
const target = resolveRasterImageCanvasRenderTarget({
|
|
3052
|
+
item,
|
|
3053
|
+
href: item.imageRasterHref,
|
|
3054
|
+
intrinsicSize: item.imageIntrinsicSize,
|
|
3055
|
+
sourceSize,
|
|
3056
|
+
contentRect,
|
|
3057
|
+
targetSize,
|
|
3058
|
+
viewportSize,
|
|
3059
|
+
cameraZoom: this.camera.zoom,
|
|
3060
|
+
options
|
|
3061
|
+
});
|
|
3062
|
+
const rasterCanvas = this.ensureRasterImageCanvas(cached);
|
|
3063
|
+
this.positionRasterImageCanvas(rasterCanvas, target.contentRect);
|
|
3064
|
+
if (rasterCanvas.itemHref !== null && rasterCanvas.itemHref !== item.imageRasterHref) {
|
|
3065
|
+
this.clearRasterImageCanvasBitmap(rasterCanvas);
|
|
3066
|
+
}
|
|
3067
|
+
if (!shouldRedrawRasterImageCanvas({
|
|
3068
|
+
currentSourceKey: rasterCanvas.sourceKey,
|
|
3069
|
+
currentWidth: rasterCanvas.width,
|
|
3070
|
+
currentHeight: rasterCanvas.height,
|
|
3071
|
+
nextSourceKey: target.sourceKey,
|
|
3072
|
+
nextWidth: target.targetSize.width,
|
|
3073
|
+
nextHeight: target.targetSize.height,
|
|
3074
|
+
upscaleRedrawRatio: options.upscaleRedrawRatio
|
|
3075
|
+
})) {
|
|
3076
|
+
return;
|
|
3077
|
+
}
|
|
3078
|
+
const request = {
|
|
3079
|
+
itemHref: item.imageRasterHref,
|
|
3080
|
+
target
|
|
3081
|
+
};
|
|
3082
|
+
if (rasterCanvas.abortController) {
|
|
3083
|
+
if (rasterCanvas.loadingItemHref !== item.imageRasterHref) {
|
|
3084
|
+
rasterCanvas.abortController.abort();
|
|
3085
|
+
rasterCanvas.abortController = null;
|
|
3086
|
+
rasterCanvas.loadingItemHref = null;
|
|
3087
|
+
rasterCanvas.loadingSourceKey = null;
|
|
3088
|
+
rasterCanvas.loadingWidth = 0;
|
|
3089
|
+
rasterCanvas.loadingHeight = 0;
|
|
3090
|
+
rasterCanvas.queuedTarget = null;
|
|
3091
|
+
this.drawRasterImageCanvas(rasterCanvas, request);
|
|
3092
|
+
return;
|
|
3093
|
+
}
|
|
3094
|
+
if (rasterCanvas.loadingSourceKey === target.sourceKey && rasterCanvas.loadingWidth === target.targetSize.width && rasterCanvas.loadingHeight === target.targetSize.height) {
|
|
3095
|
+
return;
|
|
3096
|
+
}
|
|
3097
|
+
if (shouldRedrawRasterImageCanvas({
|
|
3098
|
+
currentSourceKey: rasterCanvas.loadingSourceKey,
|
|
3099
|
+
currentWidth: rasterCanvas.loadingWidth,
|
|
3100
|
+
currentHeight: rasterCanvas.loadingHeight,
|
|
3101
|
+
nextSourceKey: target.sourceKey,
|
|
3102
|
+
nextWidth: target.targetSize.width,
|
|
3103
|
+
nextHeight: target.targetSize.height,
|
|
3104
|
+
upscaleRedrawRatio: options.upscaleRedrawRatio
|
|
3105
|
+
})) {
|
|
3106
|
+
rasterCanvas.queuedTarget = request;
|
|
3107
|
+
}
|
|
3108
|
+
return;
|
|
3109
|
+
}
|
|
3110
|
+
this.drawRasterImageCanvas(rasterCanvas, request);
|
|
3111
|
+
}
|
|
3112
|
+
ensureRasterImageCanvas(cached) {
|
|
3113
|
+
if (cached.rasterCanvas) {
|
|
3114
|
+
if (!cached.rasterCanvas.foreignObject.isConnected) {
|
|
3115
|
+
cached.g.appendChild(cached.rasterCanvas.foreignObject);
|
|
3116
|
+
}
|
|
3117
|
+
return cached.rasterCanvas;
|
|
3118
|
+
}
|
|
3119
|
+
const foreignObject = document.createElementNS(
|
|
3120
|
+
"http://www.w3.org/2000/svg",
|
|
3121
|
+
"foreignObject"
|
|
3122
|
+
);
|
|
3123
|
+
foreignObject.setAttribute("data-canvu-raster-canvas", "true");
|
|
3124
|
+
foreignObject.style.pointerEvents = "none";
|
|
3125
|
+
const canvas = document.createElement("canvas");
|
|
3126
|
+
canvas.width = 1;
|
|
3127
|
+
canvas.height = 1;
|
|
3128
|
+
canvas.style.display = "block";
|
|
3129
|
+
canvas.style.width = "100%";
|
|
3130
|
+
canvas.style.height = "100%";
|
|
3131
|
+
foreignObject.appendChild(canvas);
|
|
3132
|
+
cached.g.appendChild(foreignObject);
|
|
3133
|
+
cached.rasterCanvas = {
|
|
3134
|
+
foreignObject,
|
|
3135
|
+
canvas,
|
|
3136
|
+
itemHref: null,
|
|
3137
|
+
sourceKey: null,
|
|
3138
|
+
width: 0,
|
|
3139
|
+
height: 0,
|
|
3140
|
+
loadSequence: 0,
|
|
3141
|
+
abortController: null,
|
|
3142
|
+
loadingItemHref: null,
|
|
3143
|
+
loadingSourceKey: null,
|
|
3144
|
+
loadingWidth: 0,
|
|
3145
|
+
loadingHeight: 0,
|
|
3146
|
+
queuedTarget: null
|
|
3147
|
+
};
|
|
3148
|
+
return cached.rasterCanvas;
|
|
3149
|
+
}
|
|
3150
|
+
positionRasterImageCanvas(rasterCanvas, contentRect) {
|
|
3151
|
+
rasterCanvas.foreignObject.setAttribute("x", String(contentRect.x));
|
|
3152
|
+
rasterCanvas.foreignObject.setAttribute("y", String(contentRect.y));
|
|
3153
|
+
rasterCanvas.foreignObject.setAttribute("width", String(contentRect.width));
|
|
3154
|
+
rasterCanvas.foreignObject.setAttribute("height", String(contentRect.height));
|
|
3155
|
+
}
|
|
3156
|
+
drawRasterImageCanvas(rasterCanvas, request) {
|
|
3157
|
+
const { target } = request;
|
|
3158
|
+
const width = Math.max(1, Math.round(target.targetSize.width));
|
|
3159
|
+
const height = Math.max(1, Math.round(target.targetSize.height));
|
|
3160
|
+
const sequence = rasterCanvas.loadSequence + 1;
|
|
3161
|
+
rasterCanvas.loadSequence = sequence;
|
|
3162
|
+
rasterCanvas.abortController?.abort();
|
|
3163
|
+
const abortController = new AbortController();
|
|
3164
|
+
rasterCanvas.abortController = abortController;
|
|
3165
|
+
rasterCanvas.loadingItemHref = request.itemHref;
|
|
3166
|
+
rasterCanvas.loadingSourceKey = target.sourceKey;
|
|
3167
|
+
rasterCanvas.loadingWidth = width;
|
|
3168
|
+
rasterCanvas.loadingHeight = height;
|
|
3169
|
+
rasterCanvas.queuedTarget = null;
|
|
3170
|
+
decodeRasterImage(target.href, width, height, abortController.signal).then((decoded) => {
|
|
3171
|
+
if (abortController.signal.aborted || rasterCanvas.loadSequence !== sequence) {
|
|
3172
|
+
decoded.close();
|
|
3173
|
+
return;
|
|
3174
|
+
}
|
|
3175
|
+
const context = rasterCanvas.canvas.getContext("2d");
|
|
3176
|
+
if (!context) {
|
|
3177
|
+
decoded.close();
|
|
3178
|
+
rasterCanvas.abortController = null;
|
|
3179
|
+
rasterCanvas.loadingItemHref = null;
|
|
3180
|
+
rasterCanvas.loadingSourceKey = null;
|
|
3181
|
+
rasterCanvas.loadingWidth = 0;
|
|
3182
|
+
rasterCanvas.loadingHeight = 0;
|
|
3183
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
3184
|
+
return;
|
|
3185
|
+
}
|
|
3186
|
+
rasterCanvas.canvas.width = decoded.width;
|
|
3187
|
+
rasterCanvas.canvas.height = decoded.height;
|
|
3188
|
+
context.clearRect(0, 0, decoded.width, decoded.height);
|
|
3189
|
+
decoded.draw(context);
|
|
3190
|
+
decoded.close();
|
|
3191
|
+
rasterCanvas.itemHref = request.itemHref;
|
|
3192
|
+
rasterCanvas.sourceKey = target.sourceKey;
|
|
3193
|
+
rasterCanvas.width = decoded.width;
|
|
3194
|
+
rasterCanvas.height = decoded.height;
|
|
3195
|
+
rasterCanvas.abortController = null;
|
|
3196
|
+
rasterCanvas.loadingItemHref = null;
|
|
3197
|
+
rasterCanvas.loadingSourceKey = null;
|
|
3198
|
+
rasterCanvas.loadingWidth = 0;
|
|
3199
|
+
rasterCanvas.loadingHeight = 0;
|
|
3200
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
3201
|
+
}).catch((error) => {
|
|
3202
|
+
if (abortController.signal.aborted) return;
|
|
3203
|
+
if (error instanceof Error && error.name === "AbortError") return;
|
|
3204
|
+
if (rasterCanvas.loadSequence === sequence) {
|
|
3205
|
+
rasterCanvas.abortController = null;
|
|
3206
|
+
rasterCanvas.loadingItemHref = null;
|
|
3207
|
+
rasterCanvas.loadingSourceKey = null;
|
|
3208
|
+
rasterCanvas.loadingWidth = 0;
|
|
3209
|
+
rasterCanvas.loadingHeight = 0;
|
|
3210
|
+
this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
|
|
3211
|
+
}
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
drawQueuedRasterImageCanvasTarget(rasterCanvas) {
|
|
3215
|
+
const queuedTarget = rasterCanvas.queuedTarget;
|
|
3216
|
+
if (!queuedTarget) return;
|
|
3217
|
+
rasterCanvas.queuedTarget = null;
|
|
3218
|
+
if (!shouldRedrawRasterImageCanvas({
|
|
3219
|
+
currentSourceKey: rasterCanvas.sourceKey,
|
|
3220
|
+
currentWidth: rasterCanvas.width,
|
|
3221
|
+
currentHeight: rasterCanvas.height,
|
|
3222
|
+
nextSourceKey: queuedTarget.target.sourceKey,
|
|
3223
|
+
nextWidth: queuedTarget.target.targetSize.width,
|
|
3224
|
+
nextHeight: queuedTarget.target.targetSize.height,
|
|
3225
|
+
upscaleRedrawRatio: this.rasterImageCanvasRendering?.upscaleRedrawRatio ?? 1
|
|
3226
|
+
})) {
|
|
3227
|
+
return;
|
|
3228
|
+
}
|
|
3229
|
+
this.drawRasterImageCanvas(rasterCanvas, queuedTarget);
|
|
3230
|
+
}
|
|
3231
|
+
clearRasterImageCanvasBitmap(rasterCanvas) {
|
|
3232
|
+
const context = rasterCanvas.canvas.getContext("2d");
|
|
3233
|
+
context?.clearRect(0, 0, rasterCanvas.canvas.width, rasterCanvas.canvas.height);
|
|
3234
|
+
rasterCanvas.canvas.width = 1;
|
|
3235
|
+
rasterCanvas.canvas.height = 1;
|
|
3236
|
+
rasterCanvas.itemHref = null;
|
|
3237
|
+
rasterCanvas.sourceKey = null;
|
|
3238
|
+
rasterCanvas.width = 0;
|
|
3239
|
+
rasterCanvas.height = 0;
|
|
3240
|
+
}
|
|
3241
|
+
releaseRasterImageCanvas(cached) {
|
|
3242
|
+
const rasterCanvas = cached.rasterCanvas;
|
|
3243
|
+
if (!rasterCanvas) return;
|
|
3244
|
+
rasterCanvas.abortController?.abort();
|
|
3245
|
+
rasterCanvas.loadSequence += 1;
|
|
3246
|
+
rasterCanvas.queuedTarget = null;
|
|
3247
|
+
rasterCanvas.foreignObject.remove();
|
|
3248
|
+
cached.rasterCanvas = void 0;
|
|
3249
|
+
}
|
|
2752
3250
|
applyInteractionAttributes(g, itemId) {
|
|
2753
3251
|
g.setAttribute(
|
|
2754
3252
|
"data-canvu-selected",
|
|
@@ -2761,6 +3259,9 @@ var SvgVectorRenderer = class {
|
|
|
2761
3259
|
}
|
|
2762
3260
|
destroy() {
|
|
2763
3261
|
this.resizeObserver.disconnect();
|
|
3262
|
+
for (const cached of this.itemNodeCache.values()) {
|
|
3263
|
+
this.releaseRasterImageCanvas(cached);
|
|
3264
|
+
}
|
|
2764
3265
|
this.itemNodeCache.clear();
|
|
2765
3266
|
this.liveOverlay = null;
|
|
2766
3267
|
this.svg.remove();
|