merge v0.12.0 #51
@@ -161,7 +161,9 @@
|
|||||||
maxZoom: 18,
|
maxZoom: 18,
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
|
|
||||||
const markers = [];
|
// Marker store keyed by location id so card-click can find + flash
|
||||||
|
// the matching pin (bidirectional highlight).
|
||||||
|
const markersById = {};
|
||||||
const bounds = [];
|
const bounds = [];
|
||||||
withCoords.forEach(loc => {
|
withCoords.forEach(loc => {
|
||||||
const marker = L.circleMarker(loc.latlon, {
|
const marker = L.circleMarker(loc.latlon, {
|
||||||
@@ -174,10 +176,53 @@
|
|||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
marker.bindTooltip(loc.name, { direction: 'top', offset: [0, -6] });
|
marker.bindTooltip(loc.name, { direction: 'top', offset: [0, -6] });
|
||||||
marker.on('click', () => _flashLocationCard(loc.id));
|
marker.on('click', () => _flashLocationCard(loc.id));
|
||||||
markers.push(marker);
|
markersById[loc.id] = marker;
|
||||||
bounds.push(loc.latlon);
|
bounds.push(loc.latlon);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wire up the reverse direction: hovering a card highlights its
|
||||||
|
// pin on the map. Hover-based instead of click-based because
|
||||||
|
// clicking the card navigates to the location detail page, so the
|
||||||
|
// flash would never be visible. Event delegation so cards that
|
||||||
|
// appear later (htmx swap or reorder) still work.
|
||||||
|
let _hoverPinId = null;
|
||||||
|
document.addEventListener('mouseover', (e) => {
|
||||||
|
const card = e.target.closest('.location-card');
|
||||||
|
if (!card) return;
|
||||||
|
const locId = card.dataset.locationId;
|
||||||
|
if (locId === _hoverPinId) return;
|
||||||
|
if (_hoverPinId) _unhighlightPin(_hoverPinId);
|
||||||
|
_highlightPin(locId);
|
||||||
|
_hoverPinId = locId;
|
||||||
|
});
|
||||||
|
document.addEventListener('mouseout', (e) => {
|
||||||
|
const card = e.target.closest('.location-card');
|
||||||
|
if (!card) return;
|
||||||
|
// Only un-highlight if the mouse actually left the card,
|
||||||
|
// not just moved to a child element.
|
||||||
|
const related = e.relatedTarget && e.relatedTarget.closest('.location-card');
|
||||||
|
if (related === card) return;
|
||||||
|
if (_hoverPinId) {
|
||||||
|
_unhighlightPin(_hoverPinId);
|
||||||
|
_hoverPinId = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function _highlightPin(locId) {
|
||||||
|
const marker = markersById[locId];
|
||||||
|
if (!marker) return;
|
||||||
|
marker.setStyle({ radius: 12, fillColor: '#dc2626', weight: 3 });
|
||||||
|
marker.openTooltip();
|
||||||
|
marker.bringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unhighlightPin(locId) {
|
||||||
|
const marker = markersById[locId];
|
||||||
|
if (!marker) return;
|
||||||
|
marker.setStyle({ radius: 8, fillColor: '#f48b1c', weight: 2 });
|
||||||
|
marker.closeTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
if (bounds.length === 1) {
|
if (bounds.length === 1) {
|
||||||
map.setView(bounds[0], 14);
|
map.setView(bounds[0], 14);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user