mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-21 12:52:10 -03:00
Fix canvas initialization and sizing bugs
- Add image loading validation before sending canvas data to server Prevents 'Failed to get confirmation' error when images haven't finished loading after workflow reload. Waits 100ms and checks if all layer images are complete before rendering output. - Improve layer loading error handling in CanvasState Better logging when layers fail to load from IndexedDB. Allows empty canvas as valid state instead of failing. - Add ResizeObserver for canvas container Fixes bug where canvas only shows in top half of node. Watches container size changes and triggers re-render to ensure canvas dimensions are correctly calculated after DOM layout.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user