mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-21 20:52:12 -03:00
Implement robust world-based positioning for Blend Mode menu
Redesigned the positioning system for the Blend Mode menu, inspired by the "Custom Output Area" logic. The menu now anchors precisely to the top-right corner of the viewport and stays in place during panning and zooming.
This commit is contained in:
@@ -44,6 +44,7 @@ export class CanvasInteractions {
|
||||
this.canvas.viewport.zoom = newZoom;
|
||||
this.canvas.viewport.x = worldCoords.x - (mouseBufferX / this.canvas.viewport.zoom);
|
||||
this.canvas.viewport.y = worldCoords.y - (mouseBufferY / this.canvas.viewport.zoom);
|
||||
this.canvas.onViewportChange?.();
|
||||
}
|
||||
renderAndSave(shouldSave = false) {
|
||||
this.canvas.render();
|
||||
@@ -87,6 +88,29 @@ export class CanvasInteractions {
|
||||
this.canvas.canvas.addEventListener('drop', this.handleDrop.bind(this));
|
||||
this.canvas.canvas.addEventListener('contextmenu', this.handleContextMenu.bind(this));
|
||||
}
|
||||
/**
|
||||
* Sprawdza czy punkt znajduje się w obszarze któregokolwiek z zaznaczonych layerów
|
||||
*/
|
||||
isPointInSelectedLayers(worldX, worldY) {
|
||||
for (const layer of this.canvas.canvasSelection.selectedLayers) {
|
||||
if (!layer.visible)
|
||||
continue;
|
||||
const centerX = layer.x + layer.width / 2;
|
||||
const centerY = layer.y + layer.height / 2;
|
||||
// Przekształć punkt do lokalnego układu współrzędnych layera
|
||||
const dx = worldX - centerX;
|
||||
const dy = worldY - centerY;
|
||||
const rad = -layer.rotation * Math.PI / 180;
|
||||
const rotatedX = dx * Math.cos(rad) - dy * Math.sin(rad);
|
||||
const rotatedY = dx * Math.sin(rad) + dy * Math.cos(rad);
|
||||
// Sprawdź czy punkt jest wewnątrz prostokąta layera
|
||||
if (Math.abs(rotatedX) <= layer.width / 2 &&
|
||||
Math.abs(rotatedY) <= layer.height / 2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
resetInteractionState() {
|
||||
this.interaction.mode = 'none';
|
||||
this.interaction.resizeHandle = null;
|
||||
@@ -132,9 +156,10 @@ export class CanvasInteractions {
|
||||
// 2. Inne przyciski myszy
|
||||
if (e.button === 2) { // Prawy przycisk myszy
|
||||
this.preventEventDefaults(e);
|
||||
const clickedLayerResult = this.canvas.canvasLayers.getLayerAtPosition(coords.world.x, coords.world.y);
|
||||
if (clickedLayerResult && this.canvas.canvasSelection.selectedLayers.includes(clickedLayerResult.layer)) {
|
||||
this.canvas.canvasLayers.showBlendModeMenu(coords.view.x, coords.view.y);
|
||||
// Sprawdź czy kliknięto w obszarze któregokolwiek z zaznaczonych layerów (niezależnie od przykrycia)
|
||||
if (this.isPointInSelectedLayers(coords.world.x, coords.world.y)) {
|
||||
// Nowa logika przekazuje tylko współrzędne świata, menu pozycjonuje się samo
|
||||
this.canvas.canvasLayers.showBlendModeMenu(coords.world.x, coords.world.y);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -618,6 +643,7 @@ export class CanvasInteractions {
|
||||
this.canvas.viewport.y -= dy / this.canvas.viewport.zoom;
|
||||
this.interaction.panStart = { x: e.clientX, y: e.clientY };
|
||||
this.canvas.render();
|
||||
this.canvas.onViewportChange?.();
|
||||
}
|
||||
dragLayers(worldCoords) {
|
||||
if (this.interaction.isAltPressed && !this.interaction.hasClonedInDrag && this.canvas.canvasSelection.selectedLayers.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user