diff --git a/js/CanvasIO.js b/js/CanvasIO.js index 582843a..833e480 100644 --- a/js/CanvasIO.js +++ b/js/CanvasIO.js @@ -197,6 +197,18 @@ export class CanvasIO { } async _renderOutputData() { log.info("=== RENDERING OUTPUT DATA FOR COMFYUI ==="); + // Check if layers have valid images loaded + const layersWithoutImages = this.canvas.layers.filter(layer => !layer.image || !layer.image.complete); + if (layersWithoutImages.length > 0) { + log.warn(`${layersWithoutImages.length} layer(s) have incomplete image data. Waiting for images to load...`); + // Wait a bit for images to load + await new Promise(resolve => setTimeout(resolve, 100)); + // Check again + const stillIncomplete = this.canvas.layers.filter(layer => !layer.image || !layer.image.complete); + if (stillIncomplete.length > 0) { + throw new Error(`Canvas not ready: ${stillIncomplete.length} layer(s) still have incomplete image data. Try clicking on a layer to force initialization, or wait a moment and try again.`); + } + } // Użyj zunifikowanych funkcji z CanvasLayers const imageBlob = await this.canvas.canvasLayers.getFlattenedCanvasAsBlob(); const maskBlob = await this.canvas.canvasLayers.getFlattenedMaskAsBlob(); diff --git a/js/CanvasState.js b/js/CanvasState.js index 74e6be4..3fb28b9 100644 --- a/js/CanvasState.js +++ b/js/CanvasState.js @@ -88,10 +88,10 @@ export class CanvasState { log.debug(`Output Area resized to ${this.canvas.width}x${this.canvas.height} and viewport set.`); const loadedLayers = await this._loadLayers(savedState.layers); this.canvas.layers = loadedLayers.filter((l) => l !== null); - log.info(`Loaded ${this.canvas.layers.length} layers.`); - if (this.canvas.layers.length === 0) { - log.warn("No valid layers loaded, state may be corrupted."); - return false; + log.info(`Loaded ${this.canvas.layers.length} layers from ${savedState.layers.length} saved layers.`); + if (this.canvas.layers.length === 0 && savedState.layers.length > 0) { + log.warn(`Failed to load any layers. Saved state had ${savedState.layers.length} layers but all failed to load. This may indicate corrupted IndexedDB data.`); + // Don't return false - allow empty canvas to be valid } this.canvas.updateSelectionAfterHistory(); this.canvas.render(); diff --git a/js/CanvasView.js b/js/CanvasView.js index 4b12db2..0a3659d 100644 --- a/js/CanvasView.js +++ b/js/CanvasView.js @@ -884,6 +884,12 @@ async function createCanvasWidget(node, widget, app) { if (controlsElement) { resizeObserver.observe(controlsElement); } + // Watch the canvas container itself to detect size changes and fix canvas dimensions + const canvasContainerResizeObserver = new ResizeObserver(() => { + // Force re-read of canvas dimensions on next render + canvas.render(); + }); + canvasContainerResizeObserver.observe(canvasContainer); canvas.canvas.addEventListener('focus', () => { canvasContainer.classList.add('has-focus'); }); diff --git a/src/CanvasIO.ts b/src/CanvasIO.ts index 4072a4d..c7708a8 100644 --- a/src/CanvasIO.ts +++ b/src/CanvasIO.ts @@ -217,11 +217,25 @@ export class CanvasIO { async _renderOutputData(): Promise<{ image: string, mask: string }> { log.info("=== RENDERING OUTPUT DATA FOR COMFYUI ==="); - + + // Check if layers have valid images loaded + const layersWithoutImages = this.canvas.layers.filter(layer => !layer.image || !layer.image.complete); + if (layersWithoutImages.length > 0) { + log.warn(`${layersWithoutImages.length} layer(s) have incomplete image data. Waiting for images to load...`); + // Wait a bit for images to load + await new Promise(resolve => setTimeout(resolve, 100)); + + // Check again + const stillIncomplete = this.canvas.layers.filter(layer => !layer.image || !layer.image.complete); + if (stillIncomplete.length > 0) { + throw new Error(`Canvas not ready: ${stillIncomplete.length} layer(s) still have incomplete image data. Try clicking on a layer to force initialization, or wait a moment and try again.`); + } + } + // Użyj zunifikowanych funkcji z CanvasLayers const imageBlob = await this.canvas.canvasLayers.getFlattenedCanvasAsBlob(); const maskBlob = await this.canvas.canvasLayers.getFlattenedMaskAsBlob(); - + if (!imageBlob || !maskBlob) { throw new Error("Failed to generate canvas or mask blobs"); } diff --git a/src/CanvasState.ts b/src/CanvasState.ts index 4023a0d..5687662 100644 --- a/src/CanvasState.ts +++ b/src/CanvasState.ts @@ -118,11 +118,11 @@ export class CanvasState { log.debug(`Output Area resized to ${this.canvas.width}x${this.canvas.height} and viewport set.`); const loadedLayers = await this._loadLayers(savedState.layers); this.canvas.layers = loadedLayers.filter((l): l is Layer => l !== null); - log.info(`Loaded ${this.canvas.layers.length} layers.`); + log.info(`Loaded ${this.canvas.layers.length} layers from ${savedState.layers.length} saved layers.`); - if (this.canvas.layers.length === 0) { - log.warn("No valid layers loaded, state may be corrupted."); - return false; + if (this.canvas.layers.length === 0 && savedState.layers.length > 0) { + log.warn(`Failed to load any layers. Saved state had ${savedState.layers.length} layers but all failed to load. This may indicate corrupted IndexedDB data.`); + // Don't return false - allow empty canvas to be valid } this.canvas.updateSelectionAfterHistory(); diff --git a/src/CanvasView.ts b/src/CanvasView.ts index a1940c7..d487910 100644 --- a/src/CanvasView.ts +++ b/src/CanvasView.ts @@ -1000,6 +1000,13 @@ $el("label.clipboard-switch.mask-switch", { resizeObserver.observe(controlsElement); } + // Watch the canvas container itself to detect size changes and fix canvas dimensions + const canvasContainerResizeObserver = new ResizeObserver(() => { + // Force re-read of canvas dimensions on next render + canvas.render(); + }); + canvasContainerResizeObserver.observe(canvasContainer); + canvas.canvas.addEventListener('focus', () => { canvasContainer.classList.add('has-focus'); });