Replace console statements with structured logging

Refactored Canvas.js to use the 'log' object for debug, info, and warn messages instead of console.log, console.warn, and console.error. Added more detailed and structured logging throughout the file to improve traceability and debugging, including context information for key operations such as state changes, layer management, mask editor interactions, and image processing.
This commit is contained in:
Dariusz L
2025-07-01 07:02:28 +02:00
parent d7701fd989
commit cf10322101

View File

@@ -57,7 +57,12 @@ export class Canvas {
this.interaction = this.canvasInteractions.interaction; this.interaction = this.canvasInteractions.interaction;
console.log('Canvas widget element:', this.node); log.debug('Canvas widget element:', this.node);
log.info('Canvas initialized', {
nodeId: this.node.id,
dimensions: { width: this.width, height: this.height },
viewport: this.viewport
});
this.setPreviewVisibility(false); this.setPreviewVisibility(false);
} }
@@ -89,11 +94,11 @@ export class Canvas {
*/ */
async setPreviewVisibility(visible) { async setPreviewVisibility(visible) {
this.previewVisible = visible; this.previewVisible = visible;
console.log("Canvas preview visibility set to:", visible); log.info("Canvas preview visibility set to:", visible);
const imagePreviewWidget = await this.waitForWidget("$$canvas-image-preview", this.node); const imagePreviewWidget = await this.waitForWidget("$$canvas-image-preview", this.node);
if (imagePreviewWidget) { if (imagePreviewWidget) {
console.log("Found $$canvas-image-preview widget, controlling visibility"); log.debug("Found $$canvas-image-preview widget, controlling visibility");
if (visible) { if (visible) {
if (imagePreviewWidget.options) { if (imagePreviewWidget.options) {
@@ -125,7 +130,7 @@ export class Canvas {
} }
this.render() this.render()
} else { } else {
console.warn("$$canvas-image-preview widget not found in Canvas.js"); log.warn("$$canvas-image-preview widget not found in Canvas.js");
} }
} }
@@ -134,6 +139,7 @@ export class Canvas {
* @private * @private
*/ */
_initializeModules(callbacks) { _initializeModules(callbacks) {
log.debug('Initializing Canvas modules...');
this.maskTool = new MaskTool(this, {onStateChange: this.onStateChange}); this.maskTool = new MaskTool(this, {onStateChange: this.onStateChange});
this.canvasState = new CanvasState(this); this.canvasState = new CanvasState(this);
@@ -142,6 +148,8 @@ export class Canvas {
this.canvasRenderer = new CanvasRenderer(this); this.canvasRenderer = new CanvasRenderer(this);
this.canvasIO = new CanvasIO(this); this.canvasIO = new CanvasIO(this);
this.imageReferenceManager = new ImageReferenceManager(this); this.imageReferenceManager = new ImageReferenceManager(this);
log.debug('Canvas modules initialized successfully');
} }
/** /**
@@ -179,6 +187,7 @@ export class Canvas {
* @param {boolean} replaceLast - Czy zastąpić ostatni stan w historii * @param {boolean} replaceLast - Czy zastąpić ostatni stan w historii
*/ */
saveState(replaceLast = false) { saveState(replaceLast = false) {
log.debug('Saving canvas state', { replaceLast, layersCount: this.layers.length });
this.canvasState.saveState(replaceLast); this.canvasState.saveState(replaceLast);
this.incrementOperationCount(); this.incrementOperationCount();
this._notifyStateChange(); this._notifyStateChange();
@@ -188,9 +197,15 @@ export class Canvas {
* Cofnij ostatnią operację * Cofnij ostatnią operację
*/ */
undo() { undo() {
log.info('Performing undo operation');
const historyInfo = this.canvasState.getHistoryInfo();
log.debug('History state before undo:', historyInfo);
this.canvasState.undo(); this.canvasState.undo();
this.incrementOperationCount(); this.incrementOperationCount();
this._notifyStateChange(); this._notifyStateChange();
log.debug('Undo completed, layers count:', this.layers.length);
} }
@@ -198,9 +213,15 @@ export class Canvas {
* Ponów cofniętą operację * Ponów cofniętą operację
*/ */
redo() { redo() {
log.info('Performing redo operation');
const historyInfo = this.canvasState.getHistoryInfo();
log.debug('History state before redo:', historyInfo);
this.canvasState.redo(); this.canvasState.redo();
this.incrementOperationCount(); this.incrementOperationCount();
this._notifyStateChange(); this._notifyStateChange();
log.debug('Redo completed, layers count:', this.layers.length);
} }
/** /**
@@ -225,11 +246,20 @@ export class Canvas {
*/ */
removeSelectedLayers() { removeSelectedLayers() {
if (this.selectedLayers.length > 0) { if (this.selectedLayers.length > 0) {
log.info('Removing selected layers', {
layersToRemove: this.selectedLayers.length,
totalLayers: this.layers.length
});
this.saveState(); this.saveState();
this.layers = this.layers.filter(l => !this.selectedLayers.includes(l)); this.layers = this.layers.filter(l => !this.selectedLayers.includes(l));
this.updateSelection([]); this.updateSelection([]);
this.render(); this.render();
this.saveState(); this.saveState();
log.debug('Layers removed successfully, remaining layers:', this.layers.length);
} else {
log.debug('No layers selected for removal');
} }
} }
@@ -238,8 +268,16 @@ export class Canvas {
* @param {Array} newSelection - Nowa lista zaznaczonych warstw * @param {Array} newSelection - Nowa lista zaznaczonych warstw
*/ */
updateSelection(newSelection) { updateSelection(newSelection) {
const previousSelection = this.selectedLayers.length;
this.selectedLayers = newSelection || []; this.selectedLayers = newSelection || [];
this.selectedLayer = this.selectedLayers.length > 0 ? this.selectedLayers[this.selectedLayers.length - 1] : null; this.selectedLayer = this.selectedLayers.length > 0 ? this.selectedLayers[this.selectedLayers.length - 1] : null;
log.debug('Selection updated', {
previousCount: previousSelection,
newCount: this.selectedLayers.length,
selectedLayerIds: this.selectedLayers.map(l => l.id || 'unknown')
});
if (this.onSelectionChange) { if (this.onSelectionChange) {
this.onSelectionChange(); this.onSelectionChange();
} }
@@ -283,13 +321,20 @@ export class Canvas {
* @param {boolean} sendCleanImage - Czy wysłać czysty obraz (bez maski) do editora * @param {boolean} sendCleanImage - Czy wysłać czysty obraz (bez maski) do editora
*/ */
async startMaskEditor(predefinedMask = null, sendCleanImage = true) { async startMaskEditor(predefinedMask = null, sendCleanImage = true) {
log.info('Starting mask editor', {
hasPredefinedMask: !!predefinedMask,
sendCleanImage,
layersCount: this.layers.length
});
this.savedMaskState = await this.saveMaskState(); this.savedMaskState = await this.saveMaskState();
this.maskEditorCancelled = false; this.maskEditorCancelled = false;
if (!predefinedMask && this.maskTool && this.maskTool.maskCanvas) { if (!predefinedMask && this.maskTool && this.maskTool.maskCanvas) {
try { try {
log.debug('Creating mask from current mask tool');
predefinedMask = await this.createMaskFromCurrentMask(); predefinedMask = await this.createMaskFromCurrentMask();
log.debug('Mask created from current mask tool successfully');
} catch (error) { } catch (error) {
log.warn("Could not create mask from current mask:", error); log.warn("Could not create mask from current mask:", error);
} }
@@ -299,10 +344,10 @@ export class Canvas {
let blob; let blob;
if (sendCleanImage) { if (sendCleanImage) {
log.debug('Getting flattened canvas as blob (clean image)');
blob = await this.canvasLayers.getFlattenedCanvasAsBlob(); blob = await this.canvasLayers.getFlattenedCanvasAsBlob();
} else { } else {
log.debug('Getting flattened canvas for mask editor (with mask)');
blob = await this.canvasLayers.getFlattenedCanvasForMaskEditor(); blob = await this.canvasLayers.getFlattenedCanvasForMaskEditor();
} }
@@ -311,6 +356,8 @@ export class Canvas {
return; return;
} }
log.debug('Canvas blob created successfully, size:', blob.size);
try { try {
const formData = new FormData(); const formData = new FormData();
const filename = `layerforge-mask-edit-${+new Date()}.png`; const filename = `layerforge-mask-edit-${+new Date()}.png`;
@@ -318,6 +365,8 @@ export class Canvas {
formData.append("overwrite", "true"); formData.append("overwrite", "true");
formData.append("type", "temp"); formData.append("type", "temp");
log.debug('Uploading image to server:', filename);
const response = await api.fetchApi("/upload/image", { const response = await api.fetchApi("/upload/image", {
method: "POST", method: "POST",
body: formData, body: formData,
@@ -328,6 +377,8 @@ export class Canvas {
} }
const data = await response.json(); const data = await response.json();
log.debug('Image uploaded successfully:', data);
const img = new Image(); const img = new Image();
img.src = api.apiURL(`/view?filename=${encodeURIComponent(data.name)}&type=${data.type}&subfolder=${data.subfolder}`); img.src = api.apiURL(`/view?filename=${encodeURIComponent(data.name)}&type=${data.type}&subfolder=${data.subfolder}`);
await new Promise((res, rej) => { await new Promise((res, rej) => {
@@ -337,6 +388,7 @@ export class Canvas {
this.node.imgs = [img]; this.node.imgs = [img];
log.info('Opening ComfyUI mask editor');
ComfyApp.copyToClipspace(this.node); ComfyApp.copyToClipspace(this.node);
ComfyApp.clipspace_return_node = this.node; ComfyApp.clipspace_return_node = this.node;
ComfyApp.open_maskeditor(); ComfyApp.open_maskeditor();
@@ -347,6 +399,7 @@ export class Canvas {
this.setupCancelListener(); this.setupCancelListener();
if (predefinedMask) { if (predefinedMask) {
log.debug('Will apply predefined mask when editor is ready');
this.waitForMaskEditorAndApplyMask(); this.waitForMaskEditorAndApplyMask();
} }
@@ -794,7 +847,8 @@ export class Canvas {
* Sprawdza czy mask editor został anulowany i obsługuje to odpowiednio * Sprawdza czy mask editor został anulowany i obsługuje to odpowiednio
*/ */
async handleMaskEditorClose() { async handleMaskEditorClose() {
console.log("Node object after mask editor close:", this.node); log.info("Handling mask editor close");
log.debug("Node object after mask editor close:", this.node);
if (this.maskEditorCancelled) { if (this.maskEditorCancelled) {
log.info("Mask editor was cancelled - restoring original mask state"); log.info("Mask editor was cancelled - restoring original mask state");
@@ -814,6 +868,8 @@ export class Canvas {
return; return;
} }
log.debug("Processing mask editor result, image source:", this.node.imgs[0].src.substring(0, 100) + '...');
const resultImage = new Image(); const resultImage = new Image();
resultImage.src = this.node.imgs[0].src; resultImage.src = this.node.imgs[0].src;
@@ -822,12 +878,18 @@ export class Canvas {
resultImage.onload = resolve; resultImage.onload = resolve;
resultImage.onerror = reject; resultImage.onerror = reject;
}); });
log.debug("Result image loaded successfully", {
width: resultImage.width,
height: resultImage.height
});
} catch (error) { } catch (error) {
log.error("Failed to load image from mask editor.", error); log.error("Failed to load image from mask editor.", error);
this.node.imgs = []; this.node.imgs = [];
return; return;
} }
log.debug("Creating temporary canvas for mask processing");
const tempCanvas = document.createElement('canvas'); const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.width; tempCanvas.width = this.width;
tempCanvas.height = this.height; tempCanvas.height = this.height;
@@ -835,6 +897,7 @@ export class Canvas {
tempCtx.drawImage(resultImage, 0, 0, this.width, this.height); tempCtx.drawImage(resultImage, 0, 0, this.width, this.height);
log.debug("Processing image data to create mask");
const imageData = tempCtx.getImageData(0, 0, this.width, this.height); const imageData = tempCtx.getImageData(0, 0, this.width, this.height);
const data = imageData.data; const data = imageData.data;
@@ -848,6 +911,7 @@ export class Canvas {
tempCtx.putImageData(imageData, 0, 0); tempCtx.putImageData(imageData, 0, 0);
log.debug("Converting processed mask to image");
const maskAsImage = new Image(); const maskAsImage = new Image();
maskAsImage.src = tempCanvas.toDataURL(); maskAsImage.src = tempCanvas.toDataURL();
await new Promise(resolve => maskAsImage.onload = resolve); await new Promise(resolve => maskAsImage.onload = resolve);
@@ -856,6 +920,7 @@ export class Canvas {
const destX = -this.maskTool.x; const destX = -this.maskTool.x;
const destY = -this.maskTool.y; const destY = -this.maskTool.y;
log.debug("Applying mask to canvas", { destX, destY });
maskCtx.globalCompositeOperation = 'source-over'; maskCtx.globalCompositeOperation = 'source-over';
maskCtx.clearRect(destX, destY, this.width, this.height); maskCtx.clearRect(destX, destY, this.width, this.height);
@@ -865,6 +930,7 @@ export class Canvas {
this.render(); this.render();
this.saveState(); this.saveState();
log.debug("Creating new preview image");
const new_preview = new Image(); const new_preview = new Image();
const blob = await this.canvasLayers.getFlattenedCanvasWithMaskAsBlob(); const blob = await this.canvasLayers.getFlattenedCanvasWithMaskAsBlob();
@@ -872,12 +938,15 @@ export class Canvas {
new_preview.src = URL.createObjectURL(blob); new_preview.src = URL.createObjectURL(blob);
await new Promise(r => new_preview.onload = r); await new Promise(r => new_preview.onload = r);
this.node.imgs = [new_preview]; this.node.imgs = [new_preview];
log.debug("New preview image created successfully");
} else { } else {
this.node.imgs = []; this.node.imgs = [];
log.warn("Failed to create preview blob");
} }
this.render(); this.render();
this.savedMaskState = null; this.savedMaskState = null;
log.info("Mask editor result processed successfully");
} }
} }