From 19d1f9aa529aca65fe7234b84350f7336874aeb5 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Sun, 27 Jul 2025 21:23:05 +0200 Subject: [PATCH] Move mask rendering before preview outlines The mask is now drawn after layers but before all preview outlines, ensuring correct visual stacking. The redundant mask rendering code after the preview outlines has been removed. --- js/CanvasRenderer.js | 37 +++++++++++++++++++------------------ src/CanvasRenderer.ts | 43 ++++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/js/CanvasRenderer.js b/js/CanvasRenderer.js index a827ec3..9d0afd8 100644 --- a/js/CanvasRenderer.js +++ b/js/CanvasRenderer.js @@ -46,6 +46,25 @@ export class CanvasRenderer { this.drawGrid(ctx); // Use CanvasLayers to draw layers with proper blend area support this.canvas.canvasLayers.drawLayersToContext(ctx, this.canvas.layers); + // Draw mask AFTER layers but BEFORE all preview outlines + const maskImage = this.canvas.maskTool.getMask(); + if (maskImage && this.canvas.maskTool.isOverlayVisible) { + ctx.save(); + if (this.canvas.maskTool.isActive) { + ctx.globalCompositeOperation = 'source-over'; + ctx.globalAlpha = 0.5; + } + else { + ctx.globalCompositeOperation = 'source-over'; + ctx.globalAlpha = 1.0; + } + // Renderuj maskę w jej pozycji światowej (bez przesunięcia względem bounds) + const maskWorldX = this.canvas.maskTool.x; + const maskWorldY = this.canvas.maskTool.y; + ctx.drawImage(maskImage, maskWorldX, maskWorldY); + ctx.globalAlpha = 1.0; + ctx.restore(); + } // Draw selection frames for selected layers const sortedLayers = [...this.canvas.layers].sort((a, b) => a.zIndex - b.zIndex); sortedLayers.forEach(layer => { @@ -69,24 +88,6 @@ export class CanvasRenderer { this.drawCanvasOutline(ctx); this.drawOutputAreaExtensionPreview(ctx); // Draw extension preview this.drawPendingGenerationAreas(ctx); // Draw snapshot outlines - const maskImage = this.canvas.maskTool.getMask(); - if (maskImage && this.canvas.maskTool.isOverlayVisible) { - ctx.save(); - if (this.canvas.maskTool.isActive) { - ctx.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = 0.5; - } - else { - ctx.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = 1.0; - } - // Renderuj maskę w jej pozycji światowej (bez przesunięcia względem bounds) - const maskWorldX = this.canvas.maskTool.x; - const maskWorldY = this.canvas.maskTool.y; - ctx.drawImage(maskImage, maskWorldX, maskWorldY); - ctx.globalAlpha = 1.0; - ctx.restore(); - } this.renderInteractionElements(ctx); this.canvas.shapeTool.render(ctx); this.drawMaskAreaBounds(ctx); // Draw mask area bounds when mask tool is active diff --git a/src/CanvasRenderer.ts b/src/CanvasRenderer.ts index 24a6a84..56e9ea5 100644 --- a/src/CanvasRenderer.ts +++ b/src/CanvasRenderer.ts @@ -61,6 +61,28 @@ export class CanvasRenderer { // Use CanvasLayers to draw layers with proper blend area support this.canvas.canvasLayers.drawLayersToContext(ctx, this.canvas.layers); + // Draw mask AFTER layers but BEFORE all preview outlines + const maskImage = this.canvas.maskTool.getMask(); + if (maskImage && this.canvas.maskTool.isOverlayVisible) { + ctx.save(); + + if (this.canvas.maskTool.isActive) { + ctx.globalCompositeOperation = 'source-over'; + ctx.globalAlpha = 0.5; + } else { + ctx.globalCompositeOperation = 'source-over'; + ctx.globalAlpha = 1.0; + } + + // Renderuj maskę w jej pozycji światowej (bez przesunięcia względem bounds) + const maskWorldX = this.canvas.maskTool.x; + const maskWorldY = this.canvas.maskTool.y; + ctx.drawImage(maskImage, maskWorldX, maskWorldY); + + ctx.globalAlpha = 1.0; + ctx.restore(); + } + // Draw selection frames for selected layers const sortedLayers = [...this.canvas.layers].sort((a, b) => a.zIndex - b.zIndex); sortedLayers.forEach(layer => { @@ -86,27 +108,6 @@ export class CanvasRenderer { this.drawCanvasOutline(ctx); this.drawOutputAreaExtensionPreview(ctx); // Draw extension preview this.drawPendingGenerationAreas(ctx); // Draw snapshot outlines - const maskImage = this.canvas.maskTool.getMask(); - if (maskImage && this.canvas.maskTool.isOverlayVisible) { - - ctx.save(); - - if (this.canvas.maskTool.isActive) { - ctx.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = 0.5; - } else { - ctx.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = 1.0; - } - - // Renderuj maskę w jej pozycji światowej (bez przesunięcia względem bounds) - const maskWorldX = this.canvas.maskTool.x; - const maskWorldY = this.canvas.maskTool.y; - ctx.drawImage(maskImage, maskWorldX, maskWorldY); - - ctx.globalAlpha = 1.0; - ctx.restore(); - } this.renderInteractionElements(ctx); this.canvas.shapeTool.render(ctx);