feat(map): Implement context menu auto-close on outside click and improve user interaction

- Added `handleOutsideClick` to detect clicks outside the context menu and close it automatically.
- Implemented `closeContextMenu` function to hide the context menu when necessary.
- Enhanced `isMouseOverMenuItem` logic to track mouse movements and ensure the context menu remains open when interacting with menu items.
- Improved user experience by hiding context menu items by index and restoring them after user interaction.
This commit is contained in:
ISA
2024-08-14 15:12:15 +02:00
parent 3fc73e93fb
commit 43efbec102
2 changed files with 98 additions and 21 deletions

View File

@@ -9,6 +9,7 @@ import endIcon from "../components/gisPolylines/icons/EndIcon";
import { AddSupportPointIcon, RemoveSupportPointIcon } from "../components/gisPolylines/icons/SupportPointIcons";
import { redrawPolyline } from "./mapUtils"; // Import redrawPolyline here
import { openInNewTab } from "../utils/contextMenuUtils"; // Importiere die Funktion, wenn nicht schon vorhanden
import { useState } from "react";
//----------------------------------
// geometryUtils.js
export const parsePoint = (position) => {
@@ -130,6 +131,40 @@ export const setupMarkers = async (
export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter) => {
const markers = [];
const polylines = [];
let isMouseOverMenuItem = false;
const checkMouseOverMenu = () => {
if (!isMouseOverMenuItem) {
showContextMenuItemByIndex(map, 0);
showContextMenuItemByIndex(map, 1);
closeContextMenu(); // Kontextmenü schließen, wenn die Maus nicht mehr darüber ist
}
};
const handleMouseOverMenuItem = () => {
isMouseOverMenuItem = true;
};
const handleMouseOutMenuItem = () => {
isMouseOverMenuItem = false;
setTimeout(checkMouseOverMenu, 500); // kleine Verzögerung, um sicherzustellen, dass es keine schnellen Bewegungen sind
};
const closeContextMenu = () => {
const contextMenuElement = document.querySelector(".leaflet-contextmenu");
if (contextMenuElement) {
contextMenuElement.style.display = "none"; // Kontextmenü ausblenden
}
};
const handleOutsideClick = (event) => {
const contextMenuElement = document.querySelector(".leaflet-contextmenu");
if (contextMenuElement && !contextMenuElement.contains(event.target)) {
closeContextMenu(); // Kontextmenü schließen, wenn der Klick außerhalb stattfindet
}
};
document.addEventListener("mousedown", handleOutsideClick);
linePositions.forEach((lineData, lineIndex) => {
const lineMarkers = [];
@@ -264,12 +299,23 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
}).addTo(map);
polyline.on("mouseover", (e) => {
polyline.setStyle({ weight: 10 });
polyline.setStyle({ weight: 15 });
hideContextMenuItemByIndex(map, 0);
hideContextMenuItemByIndex(map, 1);
});
polyline.on("mousedown", (e) => {
polyline.setStyle({ weight: 15 });
});
polyline.on("mouseup", (e) => {
polyline.setStyle({ weight: 15 });
});
polyline.on("mouseout", (e) => {
polyline.setStyle({ weight: 3 });
polyline.setStyle({ color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000" });
setTimeout(checkMouseOverMenu, 500);
});
polyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt", {
@@ -281,5 +327,35 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
markers.push(...lineMarkers);
});
// Add listeners to the context menu items
const contextMenuElement = document.querySelector(".leaflet-contextmenu"); // Assuming the context menu class is 'leaflet-contextmenu'
if (contextMenuElement) {
contextMenuElement.addEventListener("mouseover", handleMouseOverMenuItem);
contextMenuElement.addEventListener("mouseout", handleMouseOutMenuItem);
}
return { markers, polylines };
};
// Funktion zum Ausblenden eines Kontextmenüelements nach Index
const hideContextMenuItemByIndex = (map, index) => {
const items = map.contextmenu._items;
if (index >= 0 && index < items.length) {
const itemElement = items[index].el;
if (itemElement) {
itemElement.style.display = "none"; // Verstecke das Element
}
}
};
// Funktion zum Einblenden eines Kontextmenüelements nach Index
const showContextMenuItemByIndex = (map, index) => {
const items = map.contextmenu._items;
if (index >= 0 && index < items.length) {
const itemElement = items[index].el;
if (itemElement) {
itemElement.style.display = ""; // Zeige das Element wieder an
}
}
};