Buton disabled

This commit is contained in:
Dariusz L
2025-06-20 21:14:47 +02:00
parent 66e6e6586f
commit bea71e19e2
2 changed files with 100 additions and 61 deletions

View File

@@ -9,6 +9,7 @@ export class Canvas {
this.layers = []; this.layers = [];
this.selectedLayer = null; this.selectedLayer = null;
this.selectedLayers = []; this.selectedLayers = [];
this.onSelectionChange = null;
this.viewport = { this.viewport = {
x: -(this.width / 4), x: -(this.width / 4),
@@ -92,6 +93,16 @@ export class Canvas {
document.addEventListener('keyup', this.handleKeyUp.bind(this)); document.addEventListener('keyup', this.handleKeyUp.bind(this));
} }
updateSelection(newSelection) {
this.selectedLayers = newSelection || [];
this.selectedLayer = this.selectedLayers.length > 0 ? this.selectedLayers[this.selectedLayers.length - 1] : null;
// Wywołaj callback, jeśli istnieje, aby zaktualizować UI
if (this.onSelectionChange) {
this.onSelectionChange();
}
}
/** /**
* Resetuje stan interakcji do wartości domyślnych. * Resetuje stan interakcji do wartości domyślnych.
*/ */
@@ -113,7 +124,7 @@ export class Canvas {
// Deselekcja po szybkim kliknięciu (pseudo-double-click) // Deselekcja po szybkim kliknięciu (pseudo-double-click)
if (currentTime - this.interaction.lastClickTime < 300) { if (currentTime - this.interaction.lastClickTime < 300) {
this.selectedLayers = []; this.updateSelection([]);
this.selectedLayer = null; this.selectedLayer = null;
this.resetInteractionState(); this.resetInteractionState();
this.render(); this.render();
@@ -251,15 +262,10 @@ export class Canvas {
if (e.key === 'Delete') { if (e.key === 'Delete') {
// Szukamy indeksu w tablicy this.layers, aby go usunąć // Szukamy indeksu w tablicy this.layers, aby go usunąć
// Ale musimy usunąć wszystkie zaznaczone warstwy // Ale musimy usunąć wszystkie zaznaczone warstwy
this.selectedLayers.forEach(layerToRemove => { // Filtrujemy główną tablicę warstw, usuwając te, które są zaznaczone
const index = this.layers.indexOf(layerToRemove); this.layers = this.layers.filter(l => !this.selectedLayers.includes(l));
if (index > -1) { // Resetujemy zaznaczenie
this.layers.splice(index, 1); this.updateSelection([]);
}
});
this.selectedLayers = [];
this.selectedLayer = null;
this.render(); this.render();
return; return;
} }
@@ -355,17 +361,22 @@ export class Canvas {
this.interaction.mode = 'dragging'; this.interaction.mode = 'dragging';
this.interaction.dragStart = {...worldCoords}; this.interaction.dragStart = {...worldCoords};
let currentSelection = [...this.selectedLayers];
if (this.interaction.isCtrlPressed) { if (this.interaction.isCtrlPressed) {
const index = this.selectedLayers.indexOf(layer); const index = currentSelection.indexOf(layer);
if (index === -1) this.selectedLayers.push(layer); if (index === -1) {
else this.selectedLayers.splice(index, 1); currentSelection.push(layer);
} else {
currentSelection.splice(index, 1);
}
} else { } else {
if (!this.selectedLayers.includes(layer)) { if (!currentSelection.includes(layer)) {
this.selectedLayers = [layer]; currentSelection = [layer];
} }
} }
this.selectedLayer = this.selectedLayers.length > 0 ? this.selectedLayers[this.selectedLayers.length - 1] : null; this.updateSelection(currentSelection);
this.originalLayerPositions.clear(); this.originalLayerPositions.clear();
this.selectedLayers.forEach(l => { this.selectedLayers.forEach(l => {
@@ -384,8 +395,7 @@ export class Canvas {
startPanning(e) { startPanning(e) {
if (!this.interaction.isCtrlPressed) { if (!this.interaction.isCtrlPressed) {
this.selectedLayers = []; this.updateSelection([]);
this.selectedLayer = null;
} }
this.interaction.mode = 'panning'; this.interaction.mode = 'panning';
this.interaction.panStart = {x: e.clientX, y: e.clientY}; this.interaction.panStart = {x: e.clientX, y: e.clientY};
@@ -416,7 +426,7 @@ export class Canvas {
}); });
// Zaktualizuj zaznaczenie, aby obejmowało tylko nowe warstwy // Zaktualizuj zaznaczenie, aby obejmowało tylko nowe warstwy
this.selectedLayers = newLayers; this.updateSelection(newLayers);
this.selectedLayer = newLayers.length > 0 ? newLayers[newLayers.length - 1] : null; this.selectedLayer = newLayers.length > 0 ? newLayers[newLayers.length - 1] : null;
// Zresetuj pozycje startowe dla nowo przeciąganych klonów // Zresetuj pozycje startowe dla nowo przeciąganych klonów
@@ -591,7 +601,7 @@ export class Canvas {
}; };
this.layers.push(layer); this.layers.push(layer);
this.selectedLayer = layer; this.updateSelection([layer]);
this.render(); this.render();
console.log("Layer added successfully"); console.log("Layer added successfully");
@@ -1274,45 +1284,47 @@ export class Canvas {
} }
mirrorHorizontal() { mirrorHorizontal() {
if (!this.selectedLayer) return; if (this.selectedLayers.length === 0) return;
const tempCanvas = document.createElement('canvas'); this.selectedLayers.forEach(layer => {
const tempCtx = tempCanvas.getContext('2d'); const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.selectedLayer.image.width; const tempCtx = tempCanvas.getContext('2d');
tempCanvas.height = this.selectedLayer.image.height; tempCanvas.width = layer.image.width;
tempCanvas.height = layer.image.height;
tempCtx.translate(tempCanvas.width, 0); tempCtx.translate(tempCanvas.width, 0);
tempCtx.scale(-1, 1); tempCtx.scale(-1, 1);
tempCtx.drawImage(this.selectedLayer.image, 0, 0); tempCtx.drawImage(layer.image, 0, 0);
const newImage = new Image(); const newImage = new Image();
newImage.onload = () => { newImage.onload = () => {
this.selectedLayer.image = newImage; layer.image = newImage;
this.render(); this.render();
}; };
newImage.src = tempCanvas.toDataURL(); newImage.src = tempCanvas.toDataURL();
});
} }
mirrorVertical() { mirrorVertical() {
if (!this.selectedLayer) return; if (this.selectedLayers.length === 0) return;
const tempCanvas = document.createElement('canvas'); this.selectedLayers.forEach(layer => {
const tempCtx = tempCanvas.getContext('2d'); const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.selectedLayer.image.width; const tempCtx = tempCanvas.getContext('2d');
tempCanvas.height = this.selectedLayer.image.height; tempCanvas.width = layer.image.width;
tempCanvas.height = layer.image.height;
tempCtx.translate(0, tempCanvas.height); tempCtx.translate(0, tempCanvas.height);
tempCtx.scale(1, -1); tempCtx.scale(1, -1);
tempCtx.drawImage(this.selectedLayer.image, 0, 0); tempCtx.drawImage(layer.image, 0, 0);
const newImage = new Image(); const newImage = new Image();
newImage.onload = () => { newImage.onload = () => {
this.selectedLayer.image = newImage; layer.image = newImage;
this.render(); this.render();
}; };
newImage.src = tempCanvas.toDataURL(); newImage.src = tempCanvas.toDataURL();
});
} }
async getLayerImageData(layer) { async getLayerImageData(layer) {
try { try {
const tempCanvas = document.createElement('canvas'); const tempCanvas = document.createElement('canvas');

View File

@@ -33,6 +33,16 @@ async function createCanvasWidget(node, widget, app) {
transform: translateY(1px); transform: translateY(1px);
} }
.painter-button:disabled,
.painter-button:disabled:hover {
background: #555;
color: #888;
cursor: not-allowed;
transform: none;
box-shadow: none;
border-color: #444;
}
.painter-button.primary { .painter-button.primary {
background: linear-gradient(to bottom, #4a6cd4, #3a5cc4); background: linear-gradient(to bottom, #4a6cd4, #3a5cc4);
border-color: #2a4cb4; border-color: #2a4cb4;
@@ -286,26 +296,31 @@ async function createCanvasWidget(node, widget, app) {
}; };
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Remove Layer", textContent: "Remove Layer",
onclick: () => { onclick: () => {
const index = canvas.layers.indexOf(canvas.selectedLayer); if (canvas.selectedLayers.length > 0) {
canvas.removeLayer(index); // Tworzy nową tablicę warstw, odfiltrowując te zaznaczone
canvas.layers = canvas.layers.filter(l => !canvas.selectedLayers.includes(l));
// Czyści zaznaczenie i powiadamia UI
canvas.updateSelection([]);
canvas.render();
}
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Rotate +90°", textContent: "Rotate +90°",
onclick: () => canvas.rotateLayer(90) onclick: () => canvas.rotateLayer(90)
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Scale +5%", textContent: "Scale +5%",
onclick: () => canvas.resizeLayer(1.05) onclick: () => canvas.resizeLayer(1.05)
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Scale -5%", textContent: "Scale -5%",
onclick: () => canvas.resizeLayer(0.95) onclick: () => canvas.resizeLayer(0.95)
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Layer Up", textContent: "Layer Up",
onclick: async () => { onclick: async () => {
canvas.moveLayerUp(); canvas.moveLayerUp();
@@ -313,7 +328,7 @@ async function createCanvasWidget(node, widget, app) {
app.graph.runStep(); app.graph.runStep();
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Layer Down", textContent: "Layer Down",
onclick: async () => { onclick: async () => {
canvas.moveLayerDown(); canvas.moveLayerDown();
@@ -322,21 +337,21 @@ async function createCanvasWidget(node, widget, app) {
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Mirror H", textContent: "Mirror H",
onclick: () => { onclick: () => {
canvas.mirrorHorizontal(); canvas.mirrorHorizontal();
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Mirror V", textContent: "Mirror V",
onclick: () => { onclick: () => {
canvas.mirrorVertical(); canvas.mirrorVertical();
} }
}), }),
$el("button.painter-button", { $el("button.painter-button.requires-selection", {
textContent: "Matting", textContent: "Matting",
onclick: async () => { onclick: async () => {
try { try {
@@ -430,6 +445,18 @@ async function createCanvasWidget(node, widget, app) {
]) ])
]); ]);
const updateButtonStates = () => {
const hasSelection = canvas.selectedLayers.length > 0;
const buttonsToToggle = controlPanel.querySelectorAll('.requires-selection');
buttonsToToggle.forEach(btn => {
btn.disabled = !hasSelection;
});
};
canvas.onSelectionChange = updateButtonStates;
updateButtonStates();
const resizeObserver = new ResizeObserver((entries) => { const resizeObserver = new ResizeObserver((entries) => {
const controlsHeight = entries[0].target.offsetHeight; const controlsHeight = entries[0].target.offsetHeight;
canvasContainer.style.top = (controlsHeight + 10) + "px"; canvasContainer.style.top = (controlsHeight + 10) + "px";