Remove Polish comments and clean up codebase

Removed Polish-language and redundant comments from multiple modules, including Canvas, CanvasInteractions, CanvasLayers, CanvasRenderer, CanvasState, Canvas_view, Mask_tool, and CommonUtils. This improves code readability and maintainability by reducing clutter and focusing on self-explanatory code.
This commit is contained in:
Dariusz L
2025-06-26 05:05:42 +02:00
parent 98d5b18422
commit 93c4bfd90d
8 changed files with 16 additions and 165 deletions

View File

@@ -8,8 +8,6 @@ import {CanvasIO} from "./CanvasIO.js";
import {createModuleLogger} from "./utils/LoggerUtils.js";
import {generateUUID, snapToGrid, getSnapAdjustment, worldToLocal, localToWorld} from "./utils/CommonUtils.js";
import {withErrorHandling, safeExecute} from "./ErrorHandler.js";
// Inicjalizacja loggera dla modułu Canvas
const log = createModuleLogger('Canvas');
export class Canvas {
@@ -31,7 +29,6 @@ export class Canvas {
y: -(this.height / 4),
zoom: 0.8,
};
// Interaction state will be managed by CanvasInteractions module
this.offscreenCanvas = document.createElement('canvas');
this.offscreenCtx = this.offscreenCanvas.getContext('2d', {
@@ -48,19 +45,15 @@ export class Canvas {
this.pendingDataCheck = null;
this.maskTool = new MaskTool(this);
this.initCanvas();
this.canvasState = new CanvasState(this); // Nowy moduł zarządzania stanem
this.canvasInteractions = new CanvasInteractions(this); // Nowy moduł obsługi interakcji
this.canvasLayers = new CanvasLayers(this); // Nowy moduł operacji na warstwach
this.canvasRenderer = new CanvasRenderer(this); // Nowy moduł renderowania
this.canvasIO = new CanvasIO(this); // Nowy moduł operacji I/O
// Po utworzeniu CanvasInteractions, użyj jego interaction state
this.canvasState = new CanvasState(this);
this.canvasInteractions = new CanvasInteractions(this);
this.canvasLayers = new CanvasLayers(this);
this.canvasRenderer = new CanvasRenderer(this);
this.canvasIO = new CanvasIO(this);
this.interaction = this.canvasInteractions.interaction;
this.setupEventListeners();
this.initNodeData();
// Przeniesione do CanvasLayers
this.blendModes = this.canvasLayers.blendModes;
this.selectedBlendMode = this.canvasLayers.selectedBlendMode;
this.blendOpacity = this.canvasLayers.blendOpacity;
@@ -71,9 +64,7 @@ export class Canvas {
opacity: 1
}));
this.imageCache = new Map(); // Pamięć podręczna dla obrazów (imageId -> imageSrc)
// this.saveState(); // Wywołanie przeniesione do loadInitialState
this.imageCache = new Map();
}
async loadStateFromDB() {
@@ -91,7 +82,7 @@ export class Canvas {
log.info("No saved state found, initializing from node data.");
await this.initNodeData();
}
this.saveState(); // Save initial state to undo stack
this.saveState();
}
saveState(replaceLast = false) {
@@ -119,7 +110,6 @@ export class Canvas {
updateHistoryButtons() {
if (this.onHistoryChange) {
// Pobierz informacje o historii odpowiednią dla aktualnego trybu
const historyInfo = this.canvasState.getHistoryInfo();
this.onHistoryChange({
canUndo: historyInfo.canUndo,
@@ -153,12 +143,6 @@ export class Canvas {
this.onSelectionChange();
}
}
// Interaction methods moved to CanvasInteractions module
// Delegacja metod operacji na warstwach do CanvasLayers
async copySelectedLayers() {
return this.canvasLayers.copySelectedLayers();
}
@@ -173,41 +157,32 @@ export class Canvas {
handleMouseMove(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleMouseMove(e);
}
handleMouseUp(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleMouseUp(e);
}
handleMouseLeave(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleMouseLeave(e);
}
handleWheel(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleWheel(e);
}
handleKeyDown(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleKeyDown(e);
}
handleKeyUp(e) {
// Deleguj do CanvasInteractions
this.canvasInteractions.handleKeyUp(e);
}
// Wszystkie metody interakcji zostały przeniesione do CanvasInteractions
// Pozostawiamy tylko metody pomocnicze używane przez CanvasInteractions
isRotationHandle(x, y) {
return this.canvasLayers.isRotationHandle(x, y);
@@ -226,11 +201,10 @@ export class Canvas {
if (index >= 0 && index < this.layers.length) {
const layer = this.layers[index];
if (layer.imageId) {
// Usuń obraz z IndexedDB, jeśli nie jest używany przez inne warstwy
const isImageUsedElsewhere = this.layers.some((l, i) => i !== index && l.imageId === layer.imageId);
if (!isImageUsedElsewhere) {
await removeImage(layer.imageId);
this.imageCache.delete(layer.imageId); // Usuń z pamięci podręcznej
this.imageCache.delete(layer.imageId);
}
}
this.layers.splice(index, 1);
@@ -287,8 +261,6 @@ export class Canvas {
this.canvasRenderer.render();
}
// Rendering methods moved to CanvasRenderer
getHandles(layer) {
return this.canvasLayers.getHandles(layer);

View File

@@ -1,7 +1,5 @@
import {createModuleLogger} from "./utils/LoggerUtils.js";
import {snapToGrid, getSnapAdjustment} from "./utils/CommonUtils.js";
// Inicjalizacja loggera dla modułu CanvasInteractions
const log = createModuleLogger('CanvasInteractions');
export class CanvasInteractions {
@@ -59,7 +57,7 @@ export class CanvasInteractions {
const worldCoords = this.canvas.getMouseWorldCoordinates(e);
if (this.canvas.maskTool.isActive) {
if (e.button === 1) { // Środkowy przycisk myszy (kółko)
if (e.button === 1) {
this.startPanning(e);
this.canvas.render();
return;
@@ -156,7 +154,6 @@ export class CanvasInteractions {
return;
}
this.canvas.maskTool.handleMouseUp();
// Nie wywołujemy saveState - to już jest obsługiwane w MaskTool
this.canvas.render();
return;
}
@@ -266,8 +263,6 @@ export class CanvasInteractions {
this.canvas.viewport.y = worldCoords.y - (mouseBufferY / this.canvas.viewport.zoom);
}
this.canvas.render();
// Nie zapisujemy stanu podczas scrollowania w trybie maski
if (!this.canvas.maskTool.isActive) {
this.canvas.saveState(true);
}

View File

@@ -3,8 +3,6 @@ import {createModuleLogger} from "./utils/LoggerUtils.js";
import {generateUUID, snapToGrid, getSnapAdjustment, worldToLocal, localToWorld, createCanvas, generateUniqueFileName} from "./utils/CommonUtils.js";
import {withErrorHandling, createValidationError, safeExecute} from "./ErrorHandler.js";
import {createImageFromSource} from "./utils/ImageUtils.js";
// Inicjalizacja loggera dla modułu CanvasLayers
const log = createModuleLogger('CanvasLayers');
export class CanvasLayers {
@@ -29,9 +27,6 @@ export class CanvasLayers {
this.isAdjustingOpacity = false;
this.internalClipboard = [];
}
// Operacje na warstwach
async copySelectedLayers() {
if (this.canvas.selectedLayers.length === 0) return;
this.internalClipboard = this.canvas.selectedLayers.map(layer => ({...layer}));
@@ -118,8 +113,6 @@ export class CanvasLayers {
}
log.debug("Adding layer with image:", image);
// Wygeneruj unikalny identyfikator dla obrazu i zapisz go do IndexedDB
const imageId = generateUUID();
await saveImage(imageId, image.src);
this.canvas.imageCache.set(imageId, image.src);
@@ -155,11 +148,10 @@ export class CanvasLayers {
if (index >= 0 && index < this.canvas.layers.length) {
const layer = this.canvas.layers[index];
if (layer.imageId) {
// Usuń obraz z IndexedDB, jeśli nie jest używany przez inne warstwy
const isImageUsedElsewhere = this.canvas.layers.some((l, i) => i !== index && l.imageId === layer.imageId);
if (!isImageUsedElsewhere) {
await removeImage(layer.imageId);
this.canvas.imageCache.delete(layer.imageId); // Usuń z pamięci podręcznej
this.canvas.imageCache.delete(layer.imageId);
}
}
this.canvas.layers.splice(index, 1);
@@ -383,8 +375,6 @@ export class CanvasLayers {
this.canvas.selectedLayer = layer;
this.canvas.render();
}
// Funkcje pomocnicze dla transformacji warstw
isRotationHandle(x, y) {
if (!this.canvas.selectedLayer) return false;
@@ -470,9 +460,6 @@ export class CanvasLayers {
}
return null;
}
// Funkcje związane z blend mode i opacity
showBlendModeMenu(x, y) {
const existingMenu = document.getElementById('blend-mode-menu');
if (existingMenu) {
@@ -554,8 +541,6 @@ export class CanvasLayers {
if (this.canvas.selectedLayer) {
this.canvas.selectedLayer.opacity = slider.value / 100;
this.canvas.render();
// Funkcja fallback do zapisu
const saveWithFallback = async (fileName) => {
try {
const uniqueFileName = generateUniqueFileName(fileName, this.canvas.node.id);
@@ -634,8 +619,6 @@ export class CanvasLayers {
this.selectedBlendMode = null;
this.isAdjustingOpacity = false;
}
// Funkcje do generowania blob z canvasu
async getFlattenedCanvasAsBlob() {
return new Promise((resolve, reject) => {
const tempCanvas = document.createElement('canvas');
@@ -675,8 +658,6 @@ export class CanvasLayers {
}, 'image/png');
});
}
// Funkcja do generowania blob z zaznaczonych warstw
async getFlattenedSelectionAsBlob() {
if (this.canvas.selectedLayers.length === 0) {
return null;

View File

@@ -1,6 +1,4 @@
import {createModuleLogger} from "./utils/LoggerUtils.js";
// Inicjalizacja loggera dla modułu CanvasRenderer
const log = createModuleLogger('CanvasRenderer');
export class CanvasRenderer {
@@ -83,21 +81,15 @@ export class CanvasRenderer {
});
this.drawCanvasOutline(ctx);
// Renderowanie maski w zależności od trybu
const maskImage = this.canvas.maskTool.getMask();
if (this.canvas.maskTool.isActive) {
// W trybie maski pokazuj maskę z przezroczystością 0.5
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.5;
// Rysuj maskę w pozycji (0,0) - będzie dopasowana do obszaru canvasu
ctx.drawImage(maskImage, 0, 0);
ctx.globalAlpha = 1.0;
} else if (maskImage) {
// W trybie warstw pokazuj maskę jako widoczną, ale nieedytowalną
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 1.0;
// Rysuj maskę w pozycji (0,0) - będzie dopasowana do obszaru canvasu
ctx.drawImage(maskImage, 0, 0);
ctx.globalAlpha = 1.0;
}

View File

@@ -2,14 +2,11 @@ import {getCanvasState, setCanvasState, removeCanvasState, saveImage, getImage,
import {createModuleLogger} from "./utils/LoggerUtils.js";
import {generateUUID, cloneLayers, getStateSignature, debounce} from "./utils/CommonUtils.js";
import {withErrorHandling, safeExecute} from "./ErrorHandler.js";
// Inicjalizacja loggera dla modułu CanvasState
const log = createModuleLogger('CanvasState');
export class CanvasState {
constructor(canvas) {
this.canvas = canvas;
// Osobne stosy dla trybu warstw i trybu maski
this.layersUndoStack = [];
this.layersRedoStack = [];
this.maskUndoStack = [];
@@ -50,8 +47,6 @@ export class CanvasState {
return false;
}
log.info("Found saved state in IndexedDB.");
// Przywróć wymiary canvas
this.canvas.width = savedState.width || 512;
this.canvas.height = savedState.height || 512;
this.canvas.viewport = savedState.viewport || {
@@ -62,8 +57,6 @@ export class CanvasState {
this.canvas.updateCanvasSize(this.canvas.width, this.canvas.height, false);
log.debug(`Canvas resized to ${this.canvas.width}x${this.canvas.height} and viewport set.`);
// Załaduj warstwy
const loadedLayers = await this._loadLayers(savedState.layers);
this.canvas.layers = loadedLayers.filter(l => l !== null);
log.info(`Loaded ${this.canvas.layers.length} layers.`);
@@ -256,7 +249,6 @@ export class CanvasState {
}
saveState(replaceLast = false) {
// Sprawdź czy jesteśmy w trybie maski
if (this.canvas.maskTool && this.canvas.maskTool.isActive) {
this.saveMaskState(replaceLast);
} else {
@@ -285,8 +277,6 @@ export class CanvasState {
}
this.layersRedoStack = [];
this.canvas.updateHistoryButtons();
// Użyj debounce dla częstych zapisów
this._debouncedSave = this._debouncedSave || debounce(() => this.saveStateToDB(), 500);
this._debouncedSave();
}
@@ -297,8 +287,6 @@ export class CanvasState {
if (replaceLast && this.maskUndoStack.length > 0) {
this.maskUndoStack.pop();
}
// Klonuj aktualny stan maski
const maskCanvas = this.canvas.maskTool.getMask();
const clonedCanvas = document.createElement('canvas');
clonedCanvas.width = maskCanvas.width;
@@ -316,7 +304,6 @@ export class CanvasState {
}
undo() {
// Sprawdź czy jesteśmy w trybie maski
if (this.canvas.maskTool && this.canvas.maskTool.isActive) {
this.undoMaskState();
} else {
@@ -325,7 +312,6 @@ export class CanvasState {
}
redo() {
// Sprawdź czy jesteśmy w trybie maski
if (this.canvas.maskTool && this.canvas.maskTool.isActive) {
this.redoMaskState();
} else {
@@ -364,13 +350,9 @@ export class CanvasState {
if (this.maskUndoStack.length > 0) {
const prevState = this.maskUndoStack[this.maskUndoStack.length - 1];
// Przywróć poprzedni stan maski
const maskCanvas = this.canvas.maskTool.getMask();
const maskCtx = maskCanvas.getContext('2d');
// Wyczyść obecną maskę
maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height);
// Przywróć poprzedni stan
maskCtx.drawImage(prevState, 0, 0);
this.canvas.render();
@@ -384,14 +366,9 @@ export class CanvasState {
const nextState = this.maskRedoStack.pop();
this.maskUndoStack.push(nextState);
// Przywróć następny stan maski
const maskCanvas = this.canvas.maskTool.getMask();
const maskCtx = maskCanvas.getContext('2d');
// Wyczyść obecną maskę
maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height);
// Przywróć następny stan
maskCtx.drawImage(nextState, 0, 0);
this.canvas.render();
@@ -418,7 +395,6 @@ export class CanvasState {
* @returns {Object} Informacje o historii
*/
getHistoryInfo() {
// Zwraca dane historii w zależności od aktywnego trybu
if (this.canvas.maskTool && this.canvas.maskTool.isActive) {
return {
undoCount: this.maskUndoStack.length,

View File

@@ -340,7 +340,6 @@ async function createCanvasWidget(node, widget, app) {
canvasContainer.style.top = (controlsHeight + 10) + "px";
}
}, [
// --- Group: Help & I/O ---
$el("div.painter-button-group", {}, [
$el("button.painter-button", {
id: `open-editor-btn-${node.id}`,
@@ -407,8 +406,6 @@ async function createCanvasWidget(node, widget, app) {
]),
$el("div.painter-separator"),
// --- Group: Canvas & Layers ---
$el("div.painter-button-group", {}, [
$el("button.painter-button", {
textContent: "Canvas Size",
@@ -520,8 +517,6 @@ async function createCanvasWidget(node, widget, app) {
]),
$el("div.painter-separator"),
// --- Group: Transform ---
$el("div.painter-button-group", {}, [
$el("button.painter-button.requires-selection", {
textContent: "Rotate +90°",
@@ -546,8 +541,6 @@ async function createCanvasWidget(node, widget, app) {
]),
$el("div.painter-separator"),
// --- Group: Tools & History ---
$el("div.painter-button-group", {}, [
$el("button.painter-button.requires-selection.matting-button", {
textContent: "Matting",
@@ -577,13 +570,8 @@ async function createCanvasWidget(node, widget, app) {
const mattedImage = new Image();
mattedImage.src = result.matted_image;
await mattedImage.decode();
// Zastąp starą warstwę nową warstwą z obrazem bez tła
const newLayer = {...selectedLayer, image: mattedImage};
// Usuń starą imageId, aby wymusić zapisanie nowego obrazu
delete newLayer.imageId;
// Zastąp warstwę w tablicy zamiast dodawać nową
canvas.layers[selectedLayerIndex] = newLayer;
canvas.updateSelection([newLayer]);
canvas.render();
@@ -613,8 +601,6 @@ async function createCanvasWidget(node, widget, app) {
}),
]),
$el("div.painter-separator"),
// --- Group: Masking ---
$el("div.painter-button-group", {id: "mask-controls"}, [
$el("button.painter-button", {
id: "mask-mode-btn",
@@ -682,8 +668,6 @@ async function createCanvasWidget(node, widget, app) {
]),
$el("div.painter-separator"),
// --- Group: Cache ---
$el("div.painter-button-group", {}, [
$el("button.painter-button", {
textContent: "Clear Cache",
@@ -742,7 +726,6 @@ async function createCanvasWidget(node, widget, app) {
const triggerWidget = node.widgets.find(w => w.name === "trigger");
const updateOutput = async () => {
// Użyj funkcji fallback do zapisu
await saveWithFallback(widget.value);
triggerWidget.value = (triggerWidget.value + 1) % 99999999;
app.graph.runStep();
@@ -917,13 +900,9 @@ async function createCanvasWidget(node, widget, app) {
node.onResize();
}
};
// Globalna mapa do śledzenia wykonania dla każdego node-a
if (!window.canvasExecutionStates) {
window.canvasExecutionStates = new Map();
}
// Funkcja fallback w przypadku problemów z unikalną nazwą
const saveWithFallback = async (fileName) => {
try {
const uniqueFileName = generateUniqueFileName(fileName, node.id);
@@ -936,7 +915,6 @@ async function createCanvasWidget(node, widget, app) {
};
api.addEventListener("execution_start", async (event) => {
// Sprawdź czy event dotyczy tego konkretnego node-a
const executionData = event.detail || {};
const currentPromptId = executionData.prompt_id;
@@ -944,23 +922,16 @@ async function createCanvasWidget(node, widget, app) {
log.debug(`Widget value: ${widget.value}`);
log.debug(`Node inputs: ${node.inputs?.length || 0}`);
log.debug(`Canvas layers count: ${canvas.layers.length}`);
// Sprawdź czy już trwa wykonanie dla tego node-a
if (window.canvasExecutionStates.get(node.id)) {
log.warn(`Execution already in progress for node ${node.id}, skipping...`);
return;
}
// Ustaw flagę wykonania dla tego node-a
window.canvasExecutionStates.set(node.id, true);
try {
// Sprawdź czy canvas ma jakiekolwiek warstwy przed zapisem
if (canvas.layers.length === 0) {
log.warn(`Node ${node.id} has no layers, skipping save to server`);
// Nie zapisuj pustego canvas-a, ale nadal przetwórz dane wejściowe
} else {
// Użyj funkcji fallback do zapisu tylko jeśli są warstwy
await saveWithFallback(widget.value);
log.info(`Canvas saved to server for node ${node.id}`);
}
@@ -979,7 +950,6 @@ async function createCanvasWidget(node, widget, app) {
} catch (error) {
log.error(`Error during execution for node ${node.id}:`, error);
} finally {
// Zwolnij flagę wykonania dla tego node-a
window.canvasExecutionStates.set(node.id, false);
log.debug(`Execution completed for node ${node.id}, flag released`);
}
@@ -1029,8 +999,6 @@ app.registerExtension({
if (tooltip) {
tooltip.remove();
}
// If modal is open when node is removed, ensure it's cleaned up
const backdrop = document.querySelector('.painter-modal-backdrop');
if (backdrop && backdrop.contains(this.canvasWidget.canvas)) {
document.body.removeChild(backdrop);

View File

@@ -1,6 +1,4 @@
import {createModuleLogger} from "./utils/LoggerUtils.js";
// Inicjalizacja loggera dla modułu Mask_tool
const log = createModuleLogger('Mask_tool');
export class MaskTool {
@@ -13,7 +11,7 @@ export class MaskTool {
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.brushSoftness = 0.5;
this.isDrawing = false;
this.lastPosition = null;
@@ -27,20 +25,15 @@ export class MaskTool {
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");
@@ -49,8 +42,6 @@ export class MaskTool {
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");
@@ -79,14 +70,9 @@ export class MaskTool {
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();
}
@@ -101,15 +87,11 @@ export class MaskTool {
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,
@@ -129,8 +111,6 @@ export class MaskTool {
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();
}
@@ -145,27 +125,17 @@ export class MaskTool {
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ść)
const alpha = data[i];
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = alpha;
}
// 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;
@@ -177,8 +147,6 @@ export class MaskTool {
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);
}

View File

@@ -115,7 +115,6 @@ export function localToWorld(localX, localY, layerProps) {
export function cloneLayers(layers) {
return layers.map(layer => {
const newLayer = {...layer};
// Obiekty Image nie są klonowane, aby oszczędzać pamięć
return newLayer;
});
}