mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-21 20:52:12 -03:00
Moved CommonUtils.js, ImageUtils.js, and LoggerUtils.js to a new utils/ directory and updated all import paths accordingly throughout the codebase. Also increased the default canvas width in Canvas.js from 512 to 1024.
189 lines
6.3 KiB
JavaScript
189 lines
6.3 KiB
JavaScript
import {createModuleLogger} from "./utils/LoggerUtils.js";
|
|
|
|
// Inicjalizacja loggera dla modułu Mask_tool
|
|
const log = createModuleLogger('Mask_tool');
|
|
|
|
export class MaskTool {
|
|
constructor(canvasInstance) {
|
|
this.canvasInstance = canvasInstance;
|
|
this.mainCanvas = canvasInstance.canvas;
|
|
this.maskCanvas = document.createElement('canvas');
|
|
this.maskCtx = this.maskCanvas.getContext('2d');
|
|
|
|
this.isActive = false;
|
|
this.brushSize = 20;
|
|
this.brushStrength = 0.5;
|
|
this.brushSoftness = 0.5; // Domyślna miękkość pędzla (0 - twardy, 1 - bardzo miękki)
|
|
this.isDrawing = false;
|
|
this.lastPosition = null;
|
|
|
|
this.initMaskCanvas();
|
|
}
|
|
|
|
setBrushSoftness(softness) {
|
|
this.brushSoftness = Math.max(0, Math.min(1, softness));
|
|
}
|
|
|
|
initMaskCanvas() {
|
|
this.maskCanvas.width = this.mainCanvas.width;
|
|
this.maskCanvas.height = this.mainCanvas.height;
|
|
// Wyczyść canvas bez zapisywania do historii
|
|
this.maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height);
|
|
}
|
|
|
|
activate() {
|
|
this.isActive = true;
|
|
this.canvasInstance.interaction.mode = 'drawingMask';
|
|
|
|
// Zapisz początkowy stan maski tylko jeśli historia jest pusta
|
|
if (this.canvasInstance.canvasState && this.canvasInstance.canvasState.maskUndoStack.length === 0) {
|
|
this.canvasInstance.canvasState.saveMaskState();
|
|
}
|
|
|
|
// Aktualizuj przyciski historii po przełączeniu na tryb maski
|
|
this.canvasInstance.updateHistoryButtons();
|
|
|
|
log.info("Mask tool activated");
|
|
}
|
|
|
|
deactivate() {
|
|
this.isActive = false;
|
|
this.canvasInstance.interaction.mode = 'none';
|
|
|
|
// Aktualizuj przyciski historii po przełączeniu z trybu maski
|
|
this.canvasInstance.updateHistoryButtons();
|
|
|
|
log.info("Mask tool deactivated");
|
|
}
|
|
|
|
setBrushSize(size) {
|
|
this.brushSize = Math.max(1, size);
|
|
}
|
|
|
|
setBrushStrength(strength) {
|
|
this.brushStrength = Math.max(0, Math.min(1, strength));
|
|
}
|
|
|
|
handleMouseDown(worldCoords) {
|
|
if (!this.isActive) return;
|
|
this.isDrawing = true;
|
|
this.lastPosition = worldCoords;
|
|
this.draw(worldCoords);
|
|
}
|
|
|
|
handleMouseMove(worldCoords) {
|
|
if (!this.isActive || !this.isDrawing) return;
|
|
this.draw(worldCoords);
|
|
this.lastPosition = worldCoords;
|
|
}
|
|
|
|
handleMouseUp() {
|
|
if (!this.isActive) return;
|
|
|
|
// Jeśli narzędzie rysowało, zapisz stan maski
|
|
if (this.isDrawing) {
|
|
// Zakończ rysowanie
|
|
this.isDrawing = false;
|
|
this.lastPosition = null;
|
|
|
|
// Zapisz stan maski do historii
|
|
if (this.canvasInstance.canvasState) {
|
|
this.canvasInstance.canvasState.saveMaskState();
|
|
}
|
|
}
|
|
}
|
|
|
|
draw(worldCoords) {
|
|
if (!this.lastPosition) {
|
|
this.lastPosition = worldCoords;
|
|
}
|
|
|
|
this.maskCtx.beginPath();
|
|
this.maskCtx.moveTo(this.lastPosition.x, this.lastPosition.y);
|
|
this.maskCtx.lineTo(worldCoords.x, worldCoords.y);
|
|
|
|
// Utwórz styl pędzla w zależności od miękkości
|
|
const gradientRadius = this.brushSize / 2;
|
|
|
|
if (this.brushSoftness === 0) {
|
|
// Twardy pędzel - użyj jednolitego koloru
|
|
this.maskCtx.strokeStyle = `rgba(255, 255, 255, ${this.brushStrength})`;
|
|
} else {
|
|
// Miękki pędzel - użyj gradientu radialnego
|
|
const innerRadius = gradientRadius * this.brushSoftness;
|
|
const gradient = this.maskCtx.createRadialGradient(
|
|
worldCoords.x, worldCoords.y, innerRadius,
|
|
worldCoords.x, worldCoords.y, gradientRadius
|
|
);
|
|
gradient.addColorStop(0, `rgba(255, 255, 255, ${this.brushStrength})`);
|
|
gradient.addColorStop(1, `rgba(255, 255, 255, 0)`);
|
|
this.maskCtx.strokeStyle = gradient;
|
|
}
|
|
|
|
this.maskCtx.lineWidth = this.brushSize;
|
|
this.maskCtx.lineCap = 'round';
|
|
this.maskCtx.lineJoin = 'round';
|
|
this.maskCtx.globalCompositeOperation = 'source-over';
|
|
this.maskCtx.stroke();
|
|
}
|
|
|
|
clear() {
|
|
this.maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height);
|
|
|
|
// Zapisz stan po wyczyszczeniu maski tylko jeśli narzędzie jest aktywne
|
|
if (this.isActive && this.canvasInstance.canvasState) {
|
|
this.canvasInstance.canvasState.saveMaskState();
|
|
}
|
|
}
|
|
|
|
getMask() {
|
|
return this.maskCanvas;
|
|
}
|
|
|
|
getMaskImageWithAlpha() {
|
|
const tempCanvas = document.createElement('canvas');
|
|
tempCanvas.width = this.maskCanvas.width;
|
|
tempCanvas.height = this.maskCanvas.height;
|
|
const tempCtx = tempCanvas.getContext('2d');
|
|
|
|
// Kopiuj maskę na tymczasowy canvas
|
|
tempCtx.drawImage(this.maskCanvas, 0, 0);
|
|
|
|
// Pobierz dane pikseli
|
|
const imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
|
|
const data = imageData.data;
|
|
|
|
// Modyfikuj kanał alfa, aby zachować zróżnicowaną przezroczystość
|
|
for (let i = 0; i < data.length; i += 4) {
|
|
const alpha = data[i]; // Wartość alfa (0-255)
|
|
data[i] = 255; // Czerwony
|
|
data[i + 1] = 255; // Zielony
|
|
data[i + 2] = 255; // Niebieski
|
|
data[i + 3] = alpha; // Alfa (zachowaj oryginalną wartość)
|
|
}
|
|
|
|
// Zapisz zmodyfikowane dane pikseli
|
|
tempCtx.putImageData(imageData, 0, 0);
|
|
|
|
// Utwórz obraz z tymczasowego canvasu
|
|
const maskImage = new Image();
|
|
maskImage.src = tempCanvas.toDataURL();
|
|
return maskImage;
|
|
}
|
|
|
|
resize(width, height) {
|
|
const oldMask = this.maskCanvas;
|
|
this.maskCanvas = document.createElement('canvas');
|
|
this.maskCanvas.width = width;
|
|
this.maskCanvas.height = height;
|
|
this.maskCtx = this.maskCanvas.getContext('2d');
|
|
|
|
// Zachowaj zawartość starej maski
|
|
if (oldMask.width > 0 && oldMask.height > 0) {
|
|
this.maskCtx.drawImage(oldMask, 0, 0);
|
|
}
|
|
|
|
log.info(`Mask canvas resized to ${width}x${height}`);
|
|
}
|
|
}
|