Karte: Blickrichtungs-Kegel (Kompass) + ruhigeres Folgen (Rene: 'weiss nicht wo es ist/hinschaut')
- Standort-Punkt zeigt jetzt einen Kompass-KEGEL (wie Google Maps): CSS-Kegel im loc-icon (GL + Leaflet), deviceorientation mit webkitCompassHeading (iOS) bzw. 360-alpha (Android), Glaettung ueber kuerzesten Winkelweg, rAF-throttled. iOS-Permission via User-Geste (Follow-/Standort-Button startet den Kompass). - Follow pant nur noch bei brauchbarem Fix (accuracy < 75m) — ungenaue Positionen liessen die Karte zappeln; GPS-Fixes frischer (maximumAge 2s statt 5s). Marker aktualisiert weiterhin jeden Fix. Bump v1249
This commit is contained in:
parent
85d578874a
commit
a31d08a2dc
7 changed files with 83 additions and 22 deletions
|
|
@ -369,6 +369,7 @@ window.Page_map = (() => {
|
|||
// Follow-Mode (René 2026-06-08): Karte wandert ab jetzt mit dem Standort;
|
||||
// manuelles Verschieben beendet das Folgen (dragstart-Listener im Map-Init).
|
||||
_followGps = true;
|
||||
_startCompass(); // User-Geste → iOS-Kompass-Permission
|
||||
_updateFollowBtn();
|
||||
UI.toast.info('Karte folgt deinem Standort — zum Beenden Karte verschieben.');
|
||||
} else {
|
||||
|
|
@ -836,6 +837,42 @@ window.Page_map = (() => {
|
|||
const b = document.getElementById('map-follow-btn');
|
||||
if (b) b.style.color = _followGps ? 'var(--c-primary)' : 'var(--c-text-secondary, #9ca3af)';
|
||||
}
|
||||
|
||||
// Kompass → Blickrichtungs-Kegel am Standort-Punkt (René 2026-06-06: „fühlt sich an,
|
||||
// als ob es nicht weiß, wo es hinschaut"). iOS verlangt requestPermission in einer
|
||||
// User-Geste → Start über Follow-/Standort-Button. Karte bleibt genordet (dragRotate
|
||||
// aus), daher gilt: Bildschirm-Rotation des Kegels = Kompass-Heading direkt.
|
||||
let _compassOn = false, _compassRaf = null;
|
||||
async function _startCompass() {
|
||||
if (_compassOn || !window.DeviceOrientationEvent) return;
|
||||
_compassOn = true;
|
||||
if (typeof DeviceOrientationEvent.requestPermission === 'function') {
|
||||
try { await DeviceOrientationEvent.requestPermission(); } catch (e) {}
|
||||
}
|
||||
let smoothed = null;
|
||||
window.addEventListener('deviceorientation', e => {
|
||||
let raw = null;
|
||||
if (e.webkitCompassHeading != null) raw = e.webkitCompassHeading; // iOS
|
||||
else if (e.alpha != null && e.absolute !== false) raw = 360 - e.alpha; // Android
|
||||
if (raw == null) return;
|
||||
// Glätten über den kürzesten Winkelweg (sonst springt der Kegel bei 359↔0)
|
||||
if (smoothed == null) smoothed = raw;
|
||||
else {
|
||||
const d = ((raw - smoothed + 540) % 360) - 180;
|
||||
smoothed = (smoothed + d * 0.25 + 360) % 360;
|
||||
}
|
||||
if (_compassRaf) return;
|
||||
_compassRaf = requestAnimationFrame(() => {
|
||||
_compassRaf = null;
|
||||
const cone = document.querySelector('#central-map .loc-heading');
|
||||
if (cone) {
|
||||
cone.style.display = 'block';
|
||||
cone.style.transform = `rotate(${smoothed}deg)`;
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
function _ensureFollowBtn() {
|
||||
const host = document.getElementById('central-map');
|
||||
if (!host || document.getElementById('map-follow-btn')) { _updateFollowBtn(); return; }
|
||||
|
|
@ -853,6 +890,7 @@ window.Page_map = (() => {
|
|||
b.addEventListener('click', () => {
|
||||
if (!_userPos) { UI.toast.error('Standort noch nicht verfügbar.'); return; }
|
||||
_followGps = true;
|
||||
_startCompass(); // User-Geste → iOS-Kompass-Permission
|
||||
_mapSetView(_userPos.lat, _userPos.lon, Math.max(14, Math.round(_mapGetZoom())));
|
||||
_updateFollowBtn();
|
||||
});
|
||||
|
|
@ -1150,14 +1188,18 @@ window.Page_map = (() => {
|
|||
} else {
|
||||
const elx = document.createElement('div');
|
||||
elx.className = 'loc-icon';
|
||||
elx.innerHTML = '<div class="loc-dot"></div><div class="loc-ring"></div>';
|
||||
elx.innerHTML = '<div class="loc-heading"></div><div class="loc-dot"></div><div class="loc-ring"></div>';
|
||||
_locationMarker = new maplibregl.Marker({ element: elx, anchor: 'center' })
|
||||
.setLngLat([lon, lat]).addTo(_map);
|
||||
}
|
||||
if (_followGps && !_recActive) _map.easeTo({ center: [lon, lat], duration: 600 });
|
||||
// Pan nur bei brauchbarem Fix — ungenaue Positionen (>75 m) lassen die
|
||||
// Karte sonst zappeln („weiß nicht, wo es ist", René 2026-06-06).
|
||||
if (_followGps && !_recActive && (pos.coords.accuracy ?? 999) < 75) {
|
||||
_map.easeTo({ center: [lon, lat], duration: 600 });
|
||||
}
|
||||
},
|
||||
() => {},
|
||||
{ enableHighAccuracy: true, maximumAge: 5000, timeout: 15000 }
|
||||
{ enableHighAccuracy: true, maximumAge: 2000, timeout: 15000 }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1165,7 +1207,7 @@ window.Page_map = (() => {
|
|||
if (!window.L) return;
|
||||
const icon = L.divIcon({
|
||||
className: 'loc-icon',
|
||||
html: '<div class="loc-dot"></div><div class="loc-ring"></div>',
|
||||
html: '<div class="loc-heading"></div><div class="loc-dot"></div><div class="loc-ring"></div>',
|
||||
iconSize: [24, 24],
|
||||
iconAnchor: [12, 12],
|
||||
});
|
||||
|
|
@ -1187,10 +1229,10 @@ window.Page_map = (() => {
|
|||
icon, zIndexOffset: 500, interactive: false,
|
||||
}).addTo(_map);
|
||||
}
|
||||
if (_followGps && !_recActive) _map.panTo([lat, lon]);
|
||||
if (_followGps && !_recActive && (pos.coords.accuracy ?? 999) < 75) _map.panTo([lat, lon]);
|
||||
},
|
||||
() => {},
|
||||
{ enableHighAccuracy: true, maximumAge: 5000, timeout: 15000 }
|
||||
{ enableHighAccuracy: true, maximumAge: 2000, timeout: 15000 }
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue