fix(markers): stop wiping MapLibre's marker class (markers stacked in flow)
Re-setting el.className each render dropped the maplibregl-marker class (position:absolute), so live markers fell into document flow and stacked +32px each — vehicles drifted south, worse when zoomed out, dragging their plate labels with them. Use classList (preserve maplibregl-marker) and wrap pin+plate in a .veh-inner positioning context so a class change can't reflow. Verified: every marker now projects to dX=0,dY=0 on its coordinate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3d420fa82e
commit
50163536e3
1 changed files with 13 additions and 4 deletions
17
index.html
17
index.html
|
|
@ -176,7 +176,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Live vehicle DOM marker (locked look) ─────────────────────────── */
|
/* ── Live vehicle DOM marker (locked look) ─────────────────────────── */
|
||||||
.veh-marker { position: relative; cursor: pointer; will-change: transform; }
|
/* NOTE: never set position on .veh-marker — MapLibre's own .maplibregl-marker
|
||||||
|
class supplies position:absolute and drives placement. The plate's
|
||||||
|
positioning context is the inner wrapper below, so a class change can't
|
||||||
|
reflow the markers. */
|
||||||
|
.veh-marker { cursor: pointer; will-change: transform; }
|
||||||
|
.veh-inner { position: relative; width: 32px; height: 32px; }
|
||||||
.veh-pin {
|
.veh-pin {
|
||||||
width: 32px; height: 32px; border-radius: 50%;
|
width: 32px; height: 32px; border-radius: 50%;
|
||||||
background: var(--c, var(--parked));
|
background: var(--c, var(--parked));
|
||||||
|
|
@ -507,7 +512,7 @@ function upsertLiveMarker(p, coords, feature) {
|
||||||
if (!m) {
|
if (!m) {
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.className = 'veh-marker';
|
el.className = 'veh-marker';
|
||||||
el.innerHTML = `<div class="veh-pin"><span class="glyph"></span></div><div class="veh-plate"></div>`;
|
el.innerHTML = `<div class="veh-inner"><div class="veh-pin"><span class="glyph"></span></div><div class="veh-plate"></div></div>`;
|
||||||
el.addEventListener('mouseenter', () => { cancelPopupClose(); openPopupImei = p.imei; const f = currentLiveFeature(p.imei); if (f) showLivePopup(f); });
|
el.addEventListener('mouseenter', () => { cancelPopupClose(); openPopupImei = p.imei; const f = currentLiveFeature(p.imei); if (f) showLivePopup(f); });
|
||||||
el.addEventListener('mouseleave', () => { if (!popupStuck) schedulePopupClose(); });
|
el.addEventListener('mouseleave', () => { if (!popupStuck) schedulePopupClose(); });
|
||||||
el.addEventListener('click', e => {
|
el.addEventListener('click', e => {
|
||||||
|
|
@ -520,9 +525,13 @@ function upsertLiveMarker(p, coords, feature) {
|
||||||
} else {
|
} else {
|
||||||
m.setLngLat(coords);
|
m.setLngLat(coords);
|
||||||
}
|
}
|
||||||
// Style the (possibly reused) element to current state
|
// Style the (possibly reused) element to current state. Use classList so we
|
||||||
|
// never wipe MapLibre's own `maplibregl-marker` class (doing so dropped
|
||||||
|
// position:absolute and made markers stack in document flow — FIX).
|
||||||
const el = m.getElement();
|
const el = m.getElement();
|
||||||
el.className = 'veh-marker ' + state;
|
el.classList.add('veh-marker');
|
||||||
|
el.classList.remove('active', 'parked', 'offline');
|
||||||
|
el.classList.add(state);
|
||||||
const pin = el.querySelector('.veh-pin');
|
const pin = el.querySelector('.veh-pin');
|
||||||
pin.style.setProperty('--c', color);
|
pin.style.setProperty('--c', color);
|
||||||
const glyph = el.querySelector('.glyph');
|
const glyph = el.querySelector('.glyph');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue