mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-24 14:02:11 -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:
@@ -83,6 +83,8 @@ 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?.();
|
||||
}
|
||||
|
||||
private renderAndSave(shouldSave: boolean = false): void {
|
||||
@@ -134,6 +136,33 @@ export class CanvasInteractions {
|
||||
this.canvas.canvas.addEventListener('contextmenu', this.handleContextMenu.bind(this) as EventListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprawdza czy punkt znajduje się w obszarze któregokolwiek z zaznaczonych layerów
|
||||
*/
|
||||
isPointInSelectedLayers(worldX: number, worldY: number): boolean {
|
||||
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(): void {
|
||||
this.interaction.mode = 'none';
|
||||
this.interaction.resizeHandle = null;
|
||||
@@ -186,9 +215,10 @@ export class CanvasInteractions {
|
||||
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;
|
||||
}
|
||||
@@ -712,6 +742,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: Point): void {
|
||||
|
||||
Reference in New Issue
Block a user