Recording map: follow toggle to free-pan while riding
New ⊕ button on the recording screen toggles map auto-follow. When off, the map stays put so you can look around when unsure where you are (off the track, or the track leads where there is no road); new GPS points no longer recentre it. Tapping it back on recentres on the current position and resumes following. Default on per screen entry (not persisted). Guards followMode around panTo/setView in onPoint/onBatchUpdate/ onStateChange. Independent of the compass freeze/rotate controls.
This commit is contained in:
parent
5da02c598a
commit
d6fe47a924
6 changed files with 151 additions and 5 deletions
|
|
@ -1246,6 +1246,7 @@ select {
|
|||
.rec-mode-btn { right: 8px; bottom: 162px; font-size: 11px; }
|
||||
.rec-route-toggle { right: 8px; bottom: 200px; }
|
||||
.rec-dark-toggle { right: 8px; bottom: 238px; }
|
||||
.rec-follow-btn { right: 8px; bottom: 276px; font-size: 18px; }
|
||||
/* Dark map: invert ONLY the tile layer (overlays — track, route, roads, puck — keep
|
||||
their colours). User-tuned filter on OSM standard tiles. Applies to every Leaflet map. */
|
||||
body.dark-map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(1.5); }
|
||||
|
|
|
|||
|
|
@ -4469,6 +4469,7 @@ async function renderRecordingInline(container) {
|
|||
// BOTH directions (orange = compass, green = GPS course) for visual comparison.
|
||||
let rotOffset = 0; // 0/90/180/270 — whole-screen rotation
|
||||
let compassFrozen = false; // X button: freeze current heading
|
||||
let followMode = true; // ⊕ button: keep the map centred on the current position
|
||||
let frozenHeading = 0; // heading captured at the moment of freezing
|
||||
let smoothedHeading = null; // EMA of calibrated compass heading (deg, 0=N, CW)
|
||||
let courseHeading = null; // EMA of GPS course over ground (deg, 0=N, CW)
|
||||
|
|
@ -4634,6 +4635,26 @@ async function renderRecordingInline(container) {
|
|||
};
|
||||
btnWrap.appendChild(freezeBtn);
|
||||
|
||||
// Follow button — ⊕: toggle whether the map keeps re-centring on the current position.
|
||||
// Off = free pan (look around when lost / off-route); tapping it back on recentres now.
|
||||
let followBtn = document.createElement("button");
|
||||
followBtn.className = "rec-map-btn rec-follow-btn active";
|
||||
followBtn.textContent = "⊕"; // ⊕
|
||||
followBtn.title = "Следить за позицией";
|
||||
followBtn.onclick = () => {
|
||||
followMode = !followMode;
|
||||
followBtn.classList.toggle("active", followMode);
|
||||
if (followMode) {
|
||||
// Re-enabling: jump straight back to where we are now.
|
||||
let pts = GPS.recording.points;
|
||||
if (pts && pts.length) {
|
||||
let last = pts.slice().sort((a, b) => new Date(a.ts) - new Date(b.ts))[pts.length - 1];
|
||||
if (last) map.panTo([last.lat, last.lon]);
|
||||
}
|
||||
}
|
||||
};
|
||||
btnWrap.appendChild(followBtn);
|
||||
|
||||
// Roads toggle button
|
||||
let roadsBtn = document.createElement("button");
|
||||
roadsBtn.className = "rec-map-btn rec-roads-toggle";
|
||||
|
|
@ -4811,7 +4832,7 @@ async function renderRecordingInline(container) {
|
|||
if (ph) ph.remove();
|
||||
statusEl.textContent = "GPS OK. Начните движение...";
|
||||
statusEl.style.color = "#03dac6";
|
||||
map.setView([p.lat, p.lon], 16);
|
||||
if (followMode) map.setView([p.lat, p.lon], 16);
|
||||
} else if (state === "recording") {
|
||||
statusEl.textContent = "";
|
||||
statusEl.style.color = "";
|
||||
|
|
@ -4837,7 +4858,7 @@ async function renderRecordingInline(container) {
|
|||
let ll = [p.lat, p.lon];
|
||||
borderLine.addLatLng(ll);
|
||||
trailLine.addLatLng(ll);
|
||||
map.panTo(ll);
|
||||
if (followMode) map.panTo(ll);
|
||||
// Save position for next session start (avoid black screen)
|
||||
DB.setProfileValue("last_lat", String(p.lat));
|
||||
DB.setProfileValue("last_lon", String(p.lon));
|
||||
|
|
@ -4854,7 +4875,7 @@ async function renderRecordingInline(container) {
|
|||
if (recState === "waiting_gps") {
|
||||
statusEl.textContent = "Поиск GPS...";
|
||||
statusEl.style.color = "#ffb74d";
|
||||
map.setView([p.lat, p.lon], 15);
|
||||
if (followMode) map.setView([p.lat, p.lon], 15);
|
||||
return;
|
||||
}
|
||||
if (recState === "ready") {
|
||||
|
|
@ -5002,7 +5023,7 @@ async function renderRecordingInline(container) {
|
|||
trailLine.setLatLngs(coords);
|
||||
if (coords.length) {
|
||||
let last = coords[coords.length - 1];
|
||||
map.panTo(last);
|
||||
if (followMode) map.panTo(last);
|
||||
updateCourse(sorted[sorted.length - 1]); // course from the last point object (has bearing)
|
||||
updateMe(last);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue