Refactor mask system to use chunked canvas storage

Replaces the single large mask canvas with a chunked system, where mask data is stored in 512x512 pixel chunks. Updates all mask drawing, compositing, and manipulation logic to operate on these chunks, improving performance and scalability for large or sparse masks. The active mask canvas is now a composite of all non-empty chunks, and all mask operations (drawing, setting, clearing) are adapted to the new chunked architecture.
This commit is contained in:
Dariusz L
2025-07-26 19:19:23 +02:00
parent 14c5f291a6
commit ca9e1890c4
4 changed files with 942 additions and 289 deletions

View File

@@ -442,22 +442,12 @@ export class CanvasMask {
const maskAsImage = new Image();
maskAsImage.src = tempCanvas.toDataURL();
await new Promise(resolve => maskAsImage.onload = resolve);
const maskCtx = this.maskTool.maskCtx;
// Pozycja gdzie ma być aplikowana maska na canvas MaskTool
// MaskTool canvas ma pozycję (maskTool.x, maskTool.y) w świecie
// Maska z edytora reprezentuje output bounds, więc musimy ją umieścić
// w pozycji bounds względem pozycji MaskTool
const destX = bounds.x - this.maskTool.x;
const destY = bounds.y - this.maskTool.y;
log.debug("Applying mask to canvas", {
maskToolPos: { x: this.maskTool.x, y: this.maskTool.y },
log.debug("Applying mask using chunk system", {
boundsPos: { x: bounds.x, y: bounds.y },
destPos: { x: destX, y: destY },
maskSize: { width: bounds.width, height: bounds.height }
});
maskCtx.globalCompositeOperation = 'source-over';
maskCtx.clearRect(destX, destY, bounds.width, bounds.height);
maskCtx.drawImage(maskAsImage, destX, destY);
// Use the chunk system instead of direct canvas manipulation
this.maskTool.setMask(maskAsImage);
this.canvas.render();
this.canvas.saveState();
log.debug("Creating new preview image");