diff --git a/css/components.css b/css/components.css
index b6f713e..ede237e 100644
--- a/css/components.css
+++ b/css/components.css
@@ -148,6 +148,51 @@
border: 2px solid #fff;
}
+/* "Hier bist du"-Marker für den übermittelten/manuell eingegebenen
+ Nutzerstandort (Gitea Issue #2 "Standort auf Karte anzeigen"). */
+
+.eventmap-user-marker {
+ background: transparent;
+ border: none;
+ position: relative;
+}
+
+.eventmap-user-marker__dot {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 14px;
+ height: 14px;
+ margin: -7px 0 0 -7px;
+ background: #1a73e8;
+ border: 2px solid #fff;
+ border-radius: 50%;
+ box-shadow: var(--shadow-card);
+}
+
+.eventmap-user-marker__pulse {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 22px;
+ height: 22px;
+ margin: -11px 0 0 -11px;
+ background: rgba(26, 115, 232, 0.35);
+ border-radius: 50%;
+ animation: eventmap-user-marker-pulse 2s ease-out infinite;
+}
+
+@keyframes eventmap-user-marker-pulse {
+ 0% {
+ transform: scale(0.6);
+ opacity: 0.8;
+ }
+ 100% {
+ transform: scale(1.8);
+ opacity: 0;
+ }
+}
+
/* Karten-Popup */
.eventmap-popup {
diff --git a/js/map/mapController.js b/js/map/mapController.js
index 049ecff..82a82ab 100644
--- a/js/map/mapController.js
+++ b/js/map/mapController.js
@@ -4,16 +4,18 @@
(function () {
const { DEFAULT_MAP_CENTER } = EventMap.config;
- const { subscribe, setState, getFilteredPlaces } = EventMap.store;
+ const { subscribe, getState, setState, getFilteredPlaces } = EventMap.store;
const { getPlaceLatLng } = EventMap.models;
- const { createMarkerForPlace } = EventMap.map;
+ const { createMarkerForPlace, createUserLocationMarker } = EventMap.map;
let map = null;
let clusterGroup = null;
+ let userLocationMarker = null;
const markersByPlaceId = new Map();
let lastFilteredKey = null;
let lastSelectedPlaceId = null;
+ let lastUserLocationKey = null;
/** Günstiger Vergleichsschlüssel für eine gefilterte Trefferliste (Reihenfolge + IDs). */
function computeFilteredKey(places) {
@@ -72,6 +74,30 @@
map.setView([lat, lng], zoom);
}
+ /**
+ * Zeigt den übermittelten/manuell eingegebenen Nutzerstandort als eigenen
+ * Marker auf der Karte an (Gitea Issue #2). Läuft außerhalb der
+ * clusterGroup, damit er nie mit Ausflugsziel-Markern geclustert wird und
+ * immer sichtbar bleibt.
+ */
+ function renderUserLocation(userLocation) {
+ if (!userLocation) {
+ if (userLocationMarker) {
+ map.removeLayer(userLocationMarker);
+ userLocationMarker = null;
+ }
+ return;
+ }
+
+ const { lat, lng } = userLocation;
+ if (userLocationMarker) {
+ userLocationMarker.setLatLng([lat, lng]);
+ } else {
+ userLocationMarker = createUserLocationMarker(lat, lng);
+ userLocationMarker.addTo(map);
+ }
+ }
+
function getMapInstance() {
return map;
}
@@ -111,6 +137,10 @@
fitToPlaces(initialFiltered);
lastFilteredKey = computeFilteredKey(initialFiltered);
+ const initialUserLocation = getState().userLocation;
+ renderUserLocation(initialUserLocation);
+ lastUserLocationKey = initialUserLocation ? `${initialUserLocation.lat},${initialUserLocation.lng}` : null;
+
subscribe((state) => {
// Filter/Standort können sich ändern, ohne dass sich state.places
// ändert - daher bei jeder Store-Änderung neu filtern und nur bei
@@ -128,6 +158,14 @@
centerOnPlace(state.selectedPlaceId);
}
}
+
+ const userLocationKey = state.userLocation
+ ? `${state.userLocation.lat},${state.userLocation.lng}`
+ : null;
+ if (userLocationKey !== lastUserLocationKey) {
+ lastUserLocationKey = userLocationKey;
+ renderUserLocation(state.userLocation);
+ }
});
return map;
diff --git a/js/map/markers.js b/js/map/markers.js
index 13a8397..1ebf2d5 100644
--- a/js/map/markers.js
+++ b/js/map/markers.js
@@ -60,5 +60,34 @@
return marker;
}
+ let userLocationIcon = null;
+
+ function getUserLocationIcon() {
+ if (!userLocationIcon) {
+ userLocationIcon = L.divIcon({
+ className: 'eventmap-user-marker',
+ html: '',
+ iconSize: [22, 22],
+ iconAnchor: [11, 11],
+ });
+ }
+ return userLocationIcon;
+ }
+
+ /**
+ * Erzeugt einen (nicht klickbaren) Marker für den übermittelten/manuell
+ * eingegebenen Nutzerstandort (Gitea Issue #2 "Standort auf Karte
+ * anzeigen"). Bewusst kein Popup/Interaktion, da es kein Ausflugsziel ist.
+ */
+ function createUserLocationMarker(lat, lng) {
+ return L.marker([lat, lng], {
+ icon: getUserLocationIcon(),
+ interactive: false,
+ keyboard: false,
+ zIndexOffset: 1000,
+ });
+ }
+
EventMap.map.createMarkerForPlace = createMarkerForPlace;
+ EventMap.map.createUserLocationMarker = createUserLocationMarker;
})();