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.
@@ -1,5 +1,5 @@
1
1
  import { V as VectorSceneItem } from './types-fJNwEnHf.cjs';
2
- import { a as VectorViewportAssetStore } from './asset-store-35ysK28r.cjs';
2
+ import { a as VectorViewportAssetStore } from './raster-image-canvas-zerVYllB.cjs';
3
3
 
4
4
  declare class IndexedDbImageStore {
5
5
  private dbPromise;
@@ -1,5 +1,5 @@
1
1
  import { V as VectorSceneItem } from './types-fJNwEnHf.js';
2
- import { a as VectorViewportAssetStore } from './asset-store-D_FjW_CN.js';
2
+ import { a as VectorViewportAssetStore } from './raster-image-canvas-BZh73aoc.js';
3
3
 
4
4
  declare class IndexedDbImageStore {
5
5
  private dbPromise;
@@ -1,10 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { c as CanvasPlugin } from './types-D5d-3dvz.cjs';
2
+ import { c as CanvasPlugin } from './types-BZ9wK9Y3.cjs';
3
3
  import 'react';
4
4
  import './types-fJNwEnHf.cjs';
5
5
  import './shape-builders-DzhCOuzo.cjs';
6
+ import './raster-image-canvas-zerVYllB.cjs';
6
7
  import './link-item-BMV3VUCr.cjs';
7
- import './asset-store-35ysK28r.cjs';
8
8
  import './types-DqsqQQVf.cjs';
9
9
 
10
10
  type ChatbotPluginPanelProps = {
package/dist/chatbot.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { c as CanvasPlugin } from './types-B-Jdh-n6.js';
2
+ import { c as CanvasPlugin } from './types-94XpQMy7.js';
3
3
  import 'react';
4
4
  import './types-fJNwEnHf.js';
5
5
  import './shape-builders-xG3A66sv.js';
6
+ import './raster-image-canvas-BZh73aoc.js';
6
7
  import './link-item-COoNNvCu.js';
7
- import './asset-store-D_FjW_CN.js';
8
8
  import './types-BXa2CIrc.js';
9
9
 
10
10
  type ChatbotPluginPanelProps = {
package/dist/index.cjs CHANGED
@@ -2577,6 +2577,151 @@ function cullItemsByViewport(items, visibleWorld) {
2577
2577
  return cullItemsByViewportSpatial(items, visibleWorld, SPATIAL_CELL_SIZE);
2578
2578
  }
2579
2579
 
2580
+ // src/renderer/raster-image-canvas.ts
2581
+ var DEFAULT_PIXEL_HEADROOM = 1.5;
2582
+ var DEFAULT_MAX_PIXEL_COUNT = 12e6;
2583
+ var DEFAULT_MAX_DIMENSION = 4096;
2584
+ var DEFAULT_UPSCALE_REDRAW_RATIO = 1.15;
2585
+ function resolveRasterImageCanvasRenderingOptions(options) {
2586
+ if (!options) return null;
2587
+ const fallbackDevicePixelRatio = typeof window === "undefined" ? 1 : window.devicePixelRatio;
2588
+ return {
2589
+ resolveRenderTarget: options.resolveRenderTarget,
2590
+ devicePixelRatio: toPositiveFiniteNumber(
2591
+ options.devicePixelRatio,
2592
+ fallbackDevicePixelRatio
2593
+ ),
2594
+ pixelHeadroom: toPositiveFiniteNumber(
2595
+ options.pixelHeadroom,
2596
+ DEFAULT_PIXEL_HEADROOM
2597
+ ),
2598
+ maxPixelCount: toPositiveFiniteNumber(
2599
+ options.maxPixelCount,
2600
+ DEFAULT_MAX_PIXEL_COUNT
2601
+ ),
2602
+ maxDimension: toPositiveFiniteNumber(
2603
+ options.maxDimension,
2604
+ DEFAULT_MAX_DIMENSION
2605
+ ),
2606
+ upscaleRedrawRatio: toPositiveFiniteNumber(
2607
+ options.upscaleRedrawRatio,
2608
+ DEFAULT_UPSCALE_REDRAW_RATIO
2609
+ )
2610
+ };
2611
+ }
2612
+ function getRasterImageContentRect(item) {
2613
+ if (item.toolKind !== "image" || !item.imageIntrinsicSize) return null;
2614
+ const bounds = normalizeRect(item.bounds);
2615
+ const intrinsicWidth = Math.max(1e-6, item.imageIntrinsicSize.width);
2616
+ const intrinsicHeight = Math.max(1e-6, item.imageIntrinsicSize.height);
2617
+ const boundsAspectRatio = bounds.width / Math.max(1e-9, bounds.height);
2618
+ const imageAspectRatio = intrinsicWidth / intrinsicHeight;
2619
+ if (Math.abs(boundsAspectRatio - imageAspectRatio) < 1e-3) {
2620
+ return { x: 0, y: 0, width: bounds.width, height: bounds.height };
2621
+ }
2622
+ if (boundsAspectRatio > imageAspectRatio) {
2623
+ const height2 = bounds.height;
2624
+ const width2 = height2 * imageAspectRatio;
2625
+ return { x: (bounds.width - width2) / 2, y: 0, width: width2, height: height2 };
2626
+ }
2627
+ const width = bounds.width;
2628
+ const height = width / imageAspectRatio;
2629
+ return { x: 0, y: (bounds.height - height) / 2, width, height };
2630
+ }
2631
+ function getRasterImageCanvasTargetSize({
2632
+ intrinsicSize,
2633
+ contentRect,
2634
+ cameraZoom,
2635
+ devicePixelRatio,
2636
+ pixelHeadroom,
2637
+ maxPixelCount,
2638
+ maxDimension
2639
+ }) {
2640
+ const intrinsicWidth = Math.max(1, Math.round(intrinsicSize.width));
2641
+ const intrinsicHeight = Math.max(1, Math.round(intrinsicSize.height));
2642
+ const targetCssWidth = Math.max(1, contentRect.width * cameraZoom);
2643
+ const targetCssHeight = Math.max(1, contentRect.height * cameraZoom);
2644
+ const desiredWidth = targetCssWidth * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
2645
+ const desiredHeight = targetCssHeight * toPositiveFiniteNumber(devicePixelRatio, 1) * pixelHeadroom;
2646
+ const dimensionScale = Math.min(
2647
+ 1,
2648
+ toPositiveFiniteNumber(maxDimension, intrinsicWidth) / Math.max(intrinsicWidth, intrinsicHeight)
2649
+ );
2650
+ const pixelScale = Math.min(
2651
+ 1,
2652
+ Math.sqrt(
2653
+ toPositiveFiniteNumber(maxPixelCount, intrinsicWidth * intrinsicHeight) / (intrinsicWidth * intrinsicHeight)
2654
+ )
2655
+ );
2656
+ const viewportScale = Math.min(
2657
+ 1,
2658
+ desiredWidth / intrinsicWidth,
2659
+ desiredHeight / intrinsicHeight
2660
+ );
2661
+ const scale = Math.min(dimensionScale, pixelScale, viewportScale);
2662
+ const width = Math.max(1, Math.round(intrinsicWidth * scale));
2663
+ const height = Math.max(1, Math.round(width * (intrinsicHeight / intrinsicWidth)));
2664
+ return { width, height };
2665
+ }
2666
+ function resolveRasterImageCanvasRenderTarget({
2667
+ item,
2668
+ href,
2669
+ intrinsicSize,
2670
+ contentRect,
2671
+ targetSize,
2672
+ viewportSize,
2673
+ cameraZoom,
2674
+ options
2675
+ }) {
2676
+ const request = {
2677
+ item,
2678
+ href,
2679
+ intrinsicSize,
2680
+ contentRect,
2681
+ targetSize,
2682
+ viewportSize,
2683
+ cameraZoom,
2684
+ devicePixelRatio: options.devicePixelRatio
2685
+ };
2686
+ const resolved = options.resolveRenderTarget?.(request);
2687
+ if (typeof resolved === "string") {
2688
+ return { href: resolved, sourceKey: resolved, targetSize, contentRect };
2689
+ }
2690
+ if (resolved?.href) {
2691
+ return {
2692
+ href: resolved.href,
2693
+ sourceKey: resolved.sourceKey ?? resolved.href,
2694
+ targetSize,
2695
+ contentRect
2696
+ };
2697
+ }
2698
+ return { href, sourceKey: href, targetSize, contentRect };
2699
+ }
2700
+ function shouldRedrawRasterImageCanvas({
2701
+ currentSourceKey,
2702
+ currentWidth,
2703
+ currentHeight,
2704
+ nextSourceKey,
2705
+ nextWidth,
2706
+ nextHeight,
2707
+ upscaleRedrawRatio
2708
+ }) {
2709
+ const safeCurrentWidth = Math.max(0, Math.round(currentWidth));
2710
+ const safeCurrentHeight = Math.max(0, Math.round(currentHeight));
2711
+ const safeNextWidth = Math.max(1, Math.round(nextWidth));
2712
+ const safeNextHeight = Math.max(1, Math.round(nextHeight));
2713
+ if (!currentSourceKey || safeCurrentWidth <= 1 || safeCurrentHeight <= 1) {
2714
+ return true;
2715
+ }
2716
+ if (currentSourceKey !== nextSourceKey && safeCurrentWidth === safeNextWidth && safeCurrentHeight === safeNextHeight) {
2717
+ return true;
2718
+ }
2719
+ return safeNextWidth > safeCurrentWidth * upscaleRedrawRatio || safeNextHeight > safeCurrentHeight * upscaleRedrawRatio;
2720
+ }
2721
+ function toPositiveFiniteNumber(value, fallback) {
2722
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
2723
+ }
2724
+
2580
2725
  // src/renderer/svg-vector-renderer.ts
2581
2726
  function formatCameraTransform(camera) {
2582
2727
  const z = camera.zoom;
@@ -2601,6 +2746,87 @@ function itemClassName(item) {
2601
2746
  }
2602
2747
  return classes.join(" ");
2603
2748
  }
2749
+ async function decodeRasterImage(href, width, height, signal) {
2750
+ if (typeof createImageBitmap === "function") {
2751
+ try {
2752
+ const response = await fetch(href, { signal, credentials: "same-origin" });
2753
+ if (!response.ok) {
2754
+ throw new Error(`Failed to fetch raster image: ${response.status}`);
2755
+ }
2756
+ const blob = await response.blob();
2757
+ if (signal.aborted) throw new DOMException("Aborted", "AbortError");
2758
+ const bitmap = await createImageBitmap(blob, {
2759
+ resizeWidth: width,
2760
+ resizeHeight: height,
2761
+ resizeQuality: "high"
2762
+ });
2763
+ return {
2764
+ width: bitmap.width,
2765
+ height: bitmap.height,
2766
+ draw: (context) => {
2767
+ context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
2768
+ },
2769
+ close: () => bitmap.close()
2770
+ };
2771
+ } catch (error) {
2772
+ if (signal.aborted) throw error;
2773
+ }
2774
+ }
2775
+ const image = await loadImageElement(href, signal);
2776
+ return {
2777
+ width,
2778
+ height,
2779
+ draw: (context) => {
2780
+ context.drawImage(image, 0, 0, width, height);
2781
+ },
2782
+ close: () => {
2783
+ }
2784
+ };
2785
+ }
2786
+ function loadImageElement(href, signal) {
2787
+ return new Promise((resolve, reject) => {
2788
+ if (signal.aborted) {
2789
+ reject(new DOMException("Aborted", "AbortError"));
2790
+ return;
2791
+ }
2792
+ const image = new Image();
2793
+ const cleanup = () => {
2794
+ signal.removeEventListener("abort", abort);
2795
+ image.onload = null;
2796
+ image.onerror = null;
2797
+ };
2798
+ const abort = () => {
2799
+ cleanup();
2800
+ image.removeAttribute("src");
2801
+ reject(new DOMException("Aborted", "AbortError"));
2802
+ };
2803
+ image.decoding = "async";
2804
+ image.onload = () => {
2805
+ const decodePromise = image.decode?.();
2806
+ if (!decodePromise) {
2807
+ cleanup();
2808
+ resolve(image);
2809
+ return;
2810
+ }
2811
+ decodePromise.then(
2812
+ () => {
2813
+ cleanup();
2814
+ resolve(image);
2815
+ },
2816
+ () => {
2817
+ cleanup();
2818
+ resolve(image);
2819
+ }
2820
+ );
2821
+ };
2822
+ image.onerror = () => {
2823
+ cleanup();
2824
+ reject(new Error("Failed to load raster image"));
2825
+ };
2826
+ signal.addEventListener("abort", abort, { once: true });
2827
+ image.src = href;
2828
+ });
2829
+ }
2604
2830
  var SvgVectorRenderer = class {
2605
2831
  container;
2606
2832
  scene;
@@ -2612,10 +2838,14 @@ var SvgVectorRenderer = class {
2612
2838
  hoveredItemId = null;
2613
2839
  liveOverlay = null;
2614
2840
  resizeObserver;
2841
+ rasterImageCanvasRendering;
2615
2842
  constructor(options) {
2616
2843
  this.container = options.container;
2617
2844
  this.scene = options.scene;
2618
2845
  this.camera = options.camera;
2846
+ this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(
2847
+ options.rasterImageCanvas
2848
+ );
2619
2849
  this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2620
2850
  this.svg.setAttribute("width", "100%");
2621
2851
  this.svg.setAttribute("height", "100%");
@@ -2644,6 +2874,15 @@ var SvgVectorRenderer = class {
2644
2874
  this.applyInteractionAttributes(cached.g, id);
2645
2875
  }
2646
2876
  }
2877
+ setRasterImageCanvasRendering(options) {
2878
+ this.rasterImageCanvasRendering = resolveRasterImageCanvasRenderingOptions(options);
2879
+ if (!this.rasterImageCanvasRendering) {
2880
+ for (const cached of this.itemNodeCache.values()) {
2881
+ this.releaseRasterImageCanvas(cached);
2882
+ }
2883
+ }
2884
+ this.render();
2885
+ }
2647
2886
  /**
2648
2887
  * Reads container size, culls items, and updates the SVG (incrementally when possible).
2649
2888
  */
@@ -2717,6 +2956,7 @@ var SvgVectorRenderer = class {
2717
2956
  }
2718
2957
  for (const [id, cached] of this.itemNodeCache) {
2719
2958
  if (!visibleIds.has(id)) {
2959
+ this.releaseRasterImageCanvas(cached);
2720
2960
  cached.g.remove();
2721
2961
  }
2722
2962
  }
@@ -2749,6 +2989,7 @@ var SvgVectorRenderer = class {
2749
2989
  g.innerHTML = item.childrenSvg;
2750
2990
  cached.lastChildrenSvg = item.childrenSvg;
2751
2991
  }
2992
+ this.syncRasterImageCanvas(cached, item);
2752
2993
  const expectedPosition = previousNode ? previousNode.nextSibling : this.rootG.firstChild;
2753
2994
  if (expectedPosition !== g) {
2754
2995
  this.rootG.insertBefore(g, expectedPosition);
@@ -2756,6 +2997,228 @@ var SvgVectorRenderer = class {
2756
2997
  previousNode = g;
2757
2998
  }
2758
2999
  }
3000
+ syncRasterImageCanvas(cached, item) {
3001
+ const options = this.rasterImageCanvasRendering;
3002
+ if (!options || item.toolKind !== "image" || !item.imageRasterHref || !item.imageIntrinsicSize) {
3003
+ this.releaseRasterImageCanvas(cached);
3004
+ return;
3005
+ }
3006
+ const contentRect = getRasterImageContentRect(item);
3007
+ const viewportSize = {
3008
+ width: this.container.clientWidth,
3009
+ height: this.container.clientHeight
3010
+ };
3011
+ if (!contentRect || viewportSize.width <= 0 || viewportSize.height <= 0) {
3012
+ this.releaseRasterImageCanvas(cached);
3013
+ return;
3014
+ }
3015
+ const targetSize = getRasterImageCanvasTargetSize({
3016
+ intrinsicSize: item.imageIntrinsicSize,
3017
+ contentRect,
3018
+ cameraZoom: this.camera.zoom,
3019
+ devicePixelRatio: options.devicePixelRatio,
3020
+ pixelHeadroom: options.pixelHeadroom,
3021
+ maxPixelCount: options.maxPixelCount,
3022
+ maxDimension: options.maxDimension
3023
+ });
3024
+ const target = resolveRasterImageCanvasRenderTarget({
3025
+ item,
3026
+ href: item.imageRasterHref,
3027
+ intrinsicSize: item.imageIntrinsicSize,
3028
+ contentRect,
3029
+ targetSize,
3030
+ viewportSize,
3031
+ cameraZoom: this.camera.zoom,
3032
+ options
3033
+ });
3034
+ const rasterCanvas = this.ensureRasterImageCanvas(cached);
3035
+ this.positionRasterImageCanvas(rasterCanvas, target.contentRect);
3036
+ if (rasterCanvas.itemHref !== null && rasterCanvas.itemHref !== item.imageRasterHref) {
3037
+ this.clearRasterImageCanvasBitmap(rasterCanvas);
3038
+ }
3039
+ if (!shouldRedrawRasterImageCanvas({
3040
+ currentSourceKey: rasterCanvas.sourceKey,
3041
+ currentWidth: rasterCanvas.width,
3042
+ currentHeight: rasterCanvas.height,
3043
+ nextSourceKey: target.sourceKey,
3044
+ nextWidth: target.targetSize.width,
3045
+ nextHeight: target.targetSize.height,
3046
+ upscaleRedrawRatio: options.upscaleRedrawRatio
3047
+ })) {
3048
+ return;
3049
+ }
3050
+ const request = {
3051
+ itemHref: item.imageRasterHref,
3052
+ target
3053
+ };
3054
+ if (rasterCanvas.abortController) {
3055
+ if (rasterCanvas.loadingItemHref !== item.imageRasterHref) {
3056
+ rasterCanvas.abortController.abort();
3057
+ rasterCanvas.abortController = null;
3058
+ rasterCanvas.loadingItemHref = null;
3059
+ rasterCanvas.loadingSourceKey = null;
3060
+ rasterCanvas.loadingWidth = 0;
3061
+ rasterCanvas.loadingHeight = 0;
3062
+ rasterCanvas.queuedTarget = null;
3063
+ this.drawRasterImageCanvas(rasterCanvas, request);
3064
+ return;
3065
+ }
3066
+ if (rasterCanvas.loadingSourceKey === target.sourceKey && rasterCanvas.loadingWidth === target.targetSize.width && rasterCanvas.loadingHeight === target.targetSize.height) {
3067
+ return;
3068
+ }
3069
+ if (shouldRedrawRasterImageCanvas({
3070
+ currentSourceKey: rasterCanvas.loadingSourceKey,
3071
+ currentWidth: rasterCanvas.loadingWidth,
3072
+ currentHeight: rasterCanvas.loadingHeight,
3073
+ nextSourceKey: target.sourceKey,
3074
+ nextWidth: target.targetSize.width,
3075
+ nextHeight: target.targetSize.height,
3076
+ upscaleRedrawRatio: options.upscaleRedrawRatio
3077
+ })) {
3078
+ rasterCanvas.queuedTarget = request;
3079
+ }
3080
+ return;
3081
+ }
3082
+ this.drawRasterImageCanvas(rasterCanvas, request);
3083
+ }
3084
+ ensureRasterImageCanvas(cached) {
3085
+ if (cached.rasterCanvas) {
3086
+ if (!cached.rasterCanvas.foreignObject.isConnected) {
3087
+ cached.g.appendChild(cached.rasterCanvas.foreignObject);
3088
+ }
3089
+ return cached.rasterCanvas;
3090
+ }
3091
+ const foreignObject = document.createElementNS(
3092
+ "http://www.w3.org/2000/svg",
3093
+ "foreignObject"
3094
+ );
3095
+ foreignObject.setAttribute("data-canvu-raster-canvas", "true");
3096
+ foreignObject.style.pointerEvents = "none";
3097
+ const canvas = document.createElement("canvas");
3098
+ canvas.width = 1;
3099
+ canvas.height = 1;
3100
+ canvas.style.display = "block";
3101
+ canvas.style.width = "100%";
3102
+ canvas.style.height = "100%";
3103
+ foreignObject.appendChild(canvas);
3104
+ cached.g.appendChild(foreignObject);
3105
+ cached.rasterCanvas = {
3106
+ foreignObject,
3107
+ canvas,
3108
+ itemHref: null,
3109
+ sourceKey: null,
3110
+ width: 0,
3111
+ height: 0,
3112
+ loadSequence: 0,
3113
+ abortController: null,
3114
+ loadingItemHref: null,
3115
+ loadingSourceKey: null,
3116
+ loadingWidth: 0,
3117
+ loadingHeight: 0,
3118
+ queuedTarget: null
3119
+ };
3120
+ return cached.rasterCanvas;
3121
+ }
3122
+ positionRasterImageCanvas(rasterCanvas, contentRect) {
3123
+ rasterCanvas.foreignObject.setAttribute("x", String(contentRect.x));
3124
+ rasterCanvas.foreignObject.setAttribute("y", String(contentRect.y));
3125
+ rasterCanvas.foreignObject.setAttribute("width", String(contentRect.width));
3126
+ rasterCanvas.foreignObject.setAttribute("height", String(contentRect.height));
3127
+ }
3128
+ drawRasterImageCanvas(rasterCanvas, request) {
3129
+ const { target } = request;
3130
+ const width = Math.max(1, Math.round(target.targetSize.width));
3131
+ const height = Math.max(1, Math.round(target.targetSize.height));
3132
+ const sequence = rasterCanvas.loadSequence + 1;
3133
+ rasterCanvas.loadSequence = sequence;
3134
+ rasterCanvas.abortController?.abort();
3135
+ const abortController = new AbortController();
3136
+ rasterCanvas.abortController = abortController;
3137
+ rasterCanvas.loadingItemHref = request.itemHref;
3138
+ rasterCanvas.loadingSourceKey = target.sourceKey;
3139
+ rasterCanvas.loadingWidth = width;
3140
+ rasterCanvas.loadingHeight = height;
3141
+ rasterCanvas.queuedTarget = null;
3142
+ decodeRasterImage(target.href, width, height, abortController.signal).then((decoded) => {
3143
+ if (abortController.signal.aborted || rasterCanvas.loadSequence !== sequence) {
3144
+ decoded.close();
3145
+ return;
3146
+ }
3147
+ const context = rasterCanvas.canvas.getContext("2d");
3148
+ if (!context) {
3149
+ decoded.close();
3150
+ rasterCanvas.abortController = null;
3151
+ rasterCanvas.loadingItemHref = null;
3152
+ rasterCanvas.loadingSourceKey = null;
3153
+ rasterCanvas.loadingWidth = 0;
3154
+ rasterCanvas.loadingHeight = 0;
3155
+ this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
3156
+ return;
3157
+ }
3158
+ rasterCanvas.canvas.width = decoded.width;
3159
+ rasterCanvas.canvas.height = decoded.height;
3160
+ context.clearRect(0, 0, decoded.width, decoded.height);
3161
+ decoded.draw(context);
3162
+ decoded.close();
3163
+ rasterCanvas.itemHref = request.itemHref;
3164
+ rasterCanvas.sourceKey = target.sourceKey;
3165
+ rasterCanvas.width = decoded.width;
3166
+ rasterCanvas.height = decoded.height;
3167
+ rasterCanvas.abortController = null;
3168
+ rasterCanvas.loadingItemHref = null;
3169
+ rasterCanvas.loadingSourceKey = null;
3170
+ rasterCanvas.loadingWidth = 0;
3171
+ rasterCanvas.loadingHeight = 0;
3172
+ this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
3173
+ }).catch((error) => {
3174
+ if (abortController.signal.aborted) return;
3175
+ if (error instanceof Error && error.name === "AbortError") return;
3176
+ if (rasterCanvas.loadSequence === sequence) {
3177
+ rasterCanvas.abortController = null;
3178
+ rasterCanvas.loadingItemHref = null;
3179
+ rasterCanvas.loadingSourceKey = null;
3180
+ rasterCanvas.loadingWidth = 0;
3181
+ rasterCanvas.loadingHeight = 0;
3182
+ this.drawQueuedRasterImageCanvasTarget(rasterCanvas);
3183
+ }
3184
+ });
3185
+ }
3186
+ drawQueuedRasterImageCanvasTarget(rasterCanvas) {
3187
+ const queuedTarget = rasterCanvas.queuedTarget;
3188
+ if (!queuedTarget) return;
3189
+ rasterCanvas.queuedTarget = null;
3190
+ if (!shouldRedrawRasterImageCanvas({
3191
+ currentSourceKey: rasterCanvas.sourceKey,
3192
+ currentWidth: rasterCanvas.width,
3193
+ currentHeight: rasterCanvas.height,
3194
+ nextSourceKey: queuedTarget.target.sourceKey,
3195
+ nextWidth: queuedTarget.target.targetSize.width,
3196
+ nextHeight: queuedTarget.target.targetSize.height,
3197
+ upscaleRedrawRatio: this.rasterImageCanvasRendering?.upscaleRedrawRatio ?? 1
3198
+ })) {
3199
+ return;
3200
+ }
3201
+ this.drawRasterImageCanvas(rasterCanvas, queuedTarget);
3202
+ }
3203
+ clearRasterImageCanvasBitmap(rasterCanvas) {
3204
+ const context = rasterCanvas.canvas.getContext("2d");
3205
+ context?.clearRect(0, 0, rasterCanvas.canvas.width, rasterCanvas.canvas.height);
3206
+ rasterCanvas.canvas.width = 1;
3207
+ rasterCanvas.canvas.height = 1;
3208
+ rasterCanvas.itemHref = null;
3209
+ rasterCanvas.sourceKey = null;
3210
+ rasterCanvas.width = 0;
3211
+ rasterCanvas.height = 0;
3212
+ }
3213
+ releaseRasterImageCanvas(cached) {
3214
+ const rasterCanvas = cached.rasterCanvas;
3215
+ if (!rasterCanvas) return;
3216
+ rasterCanvas.abortController?.abort();
3217
+ rasterCanvas.loadSequence += 1;
3218
+ rasterCanvas.queuedTarget = null;
3219
+ rasterCanvas.foreignObject.remove();
3220
+ cached.rasterCanvas = void 0;
3221
+ }
2759
3222
  applyInteractionAttributes(g, itemId) {
2760
3223
  g.setAttribute(
2761
3224
  "data-canvu-selected",
@@ -2768,6 +3231,9 @@ var SvgVectorRenderer = class {
2768
3231
  }
2769
3232
  destroy() {
2770
3233
  this.resizeObserver.disconnect();
3234
+ for (const cached of this.itemNodeCache.values()) {
3235
+ this.releaseRasterImageCanvas(cached);
3236
+ }
2771
3237
  this.itemNodeCache.clear();
2772
3238
  this.liveOverlay = null;
2773
3239
  this.svg.remove();