feat: Karte reagiert auf Karussell-Wechsel
- Map-Instanz wird einmalig erstellt, Marker dynamisch gewechselt - data-lage Attribute auf Carousel-Cards fuer Lagen-Zuordnung - Bei Lage mit Daten: Marker + Legende angezeigt - Bei Platzhalter: Karte ausgeblendet, 'Kartendaten folgen' - Zukunftssicher: Neue Lagen brauchen nur data-lage + summary.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -71,6 +71,12 @@
|
||||
|
||||
if (videos.length > 1) startRotation();
|
||||
|
||||
/* ==================== MAP STATE ==================== */
|
||||
var mapInstance = null;
|
||||
var markerLayer = null;
|
||||
var legendControl = null;
|
||||
var lageData = {};
|
||||
|
||||
/* ==================== 3D CAROUSEL ==================== */
|
||||
var cards = document.querySelectorAll('.carousel-card');
|
||||
var dots = document.querySelectorAll('.carousel-dot');
|
||||
@@ -88,6 +94,16 @@
|
||||
dots.forEach(function (dot, i) {
|
||||
dot.classList.toggle('active', i === idx);
|
||||
});
|
||||
// Update map based on active Lage
|
||||
var lage = cards[idx].getAttribute('data-lage');
|
||||
var mapSection = document.getElementById('map-section');
|
||||
if (lage && lageData[lage]) {
|
||||
mapSection.classList.remove('map-hidden');
|
||||
showMarkers(lageData[lage].locations, lageData[lage].category_labels);
|
||||
} else {
|
||||
if (mapSection) mapSection.classList.add('map-hidden');
|
||||
clearMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
cards.forEach(function (card, i) {
|
||||
@@ -188,50 +204,59 @@ function mdToHtml(md) {
|
||||
excerptEl.innerHTML = mdToHtml(data.zusammenfassung);
|
||||
}
|
||||
|
||||
// Map
|
||||
if (data.locations && data.locations.length > 0) {
|
||||
initMap(data.locations, data.category_labels || {});
|
||||
}
|
||||
// Store data and init map
|
||||
lageData['iran-konflikt'] = {
|
||||
locations: data.locations || [],
|
||||
category_labels: data.category_labels || {}
|
||||
};
|
||||
createMap();
|
||||
showMarkers(data.locations || [], data.category_labels || {});
|
||||
})
|
||||
.catch(function () {
|
||||
});
|
||||
}
|
||||
|
||||
/* ==================== LEAFLET MAP (exact lagebild style) ==================== */
|
||||
function initMap(locations, apiLabels) {
|
||||
/* ==================== LEAFLET MAP ==================== */
|
||||
function clearMarkers() {
|
||||
if (markerLayer) markerLayer.clearLayers();
|
||||
if (legendControl && mapInstance) { mapInstance.removeControl(legendControl); legendControl = null; }
|
||||
}
|
||||
|
||||
function createMap() {
|
||||
if (mapInstance) return;
|
||||
var mapEl = document.getElementById('map-container');
|
||||
if (!mapEl || typeof L === 'undefined') return;
|
||||
|
||||
var map = L.map(mapEl, {
|
||||
center: [33.0, 48.0],
|
||||
zoom: 5,
|
||||
zoomControl: true,
|
||||
scrollWheelZoom: true,
|
||||
minZoom: 2,
|
||||
maxBounds: [[-85, -180], [85, 180]],
|
||||
maxBoundsViscosity: 1.0
|
||||
mapInstance = L.map(mapEl, {
|
||||
center: [33.0, 48.0], zoom: 5, zoomControl: true, scrollWheelZoom: true,
|
||||
minZoom: 2, maxBounds: [[-85, -180], [85, 180]], maxBoundsViscosity: 1.0
|
||||
});
|
||||
|
||||
L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||
maxZoom: 19,
|
||||
noWrap: true
|
||||
}).addTo(map);
|
||||
maxZoom: 19, noWrap: true
|
||||
}).addTo(mapInstance);
|
||||
|
||||
markerLayer = L.layerGroup().addTo(mapInstance);
|
||||
setTimeout(function () { mapInstance.invalidateSize(); }, 500);
|
||||
}
|
||||
|
||||
function pulseIcon(color) {
|
||||
return L.divIcon({
|
||||
className: '',
|
||||
html: '<div class="pulse-marker-wrapper">'
|
||||
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
||||
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
||||
+ '<div class="pulse-marker-dot" style="background:' + color + ';box-shadow:0 0 10px ' + color + '"></div>'
|
||||
+ '</div>',
|
||||
iconSize: [20, 20], iconAnchor: [10, 10], popupAnchor: [0, -12]
|
||||
});
|
||||
}
|
||||
|
||||
function showMarkers(locations, apiLabels) {
|
||||
if (!mapInstance) createMap();
|
||||
clearMarkers();
|
||||
|
||||
// Exact same pulse icon as lagebild
|
||||
function pulseIcon(color) {
|
||||
return L.divIcon({
|
||||
className: '',
|
||||
html: '<div class="pulse-marker-wrapper">'
|
||||
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
||||
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
||||
+ '<div class="pulse-marker-dot" style="background:' + color + ';box-shadow:0 0 10px ' + color + '"></div>'
|
||||
+ '</div>',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor: [0, -12]
|
||||
});
|
||||
}
|
||||
|
||||
var categoryColors = {
|
||||
primary: '#ef4444',
|
||||
@@ -266,7 +291,7 @@ function mdToHtml(md) {
|
||||
popup += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>';
|
||||
|
||||
L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) })
|
||||
.addTo(map)
|
||||
.addTo(markerLayer)
|
||||
.bindPopup(popup);
|
||||
bounds.push([loc.lat, loc.lon]);
|
||||
});
|
||||
@@ -285,13 +310,13 @@ function mdToHtml(md) {
|
||||
div.innerHTML = html;
|
||||
return div;
|
||||
};
|
||||
legend.addTo(map);
|
||||
legend.addTo(mapInstance);
|
||||
|
||||
if (bounds.length > 0) {
|
||||
map.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
|
||||
mapInstance.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
|
||||
}
|
||||
|
||||
setTimeout(function () { map.invalidateSize(); }, 500);
|
||||
setTimeout(function () { mapInstance.invalidateSize(); }, 300);
|
||||
}
|
||||
|
||||
/* ==================== INIT ==================== */
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren