auto-sync: 2026-05-06 08:10:01
This commit is contained in:
84
tasks/enduro-trails/prototype/static/app.js
vendored
84
tasks/enduro-trails/prototype/static/app.js
vendored
@@ -1675,17 +1675,91 @@ function updateRulerLine() {
|
|||||||
document.getElementById('ruler-dist').textContent = dist;
|
document.getElementById('ruler-dist').textContent = dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeRulerPoint(idx) {
|
||||||
|
const map = window._map;
|
||||||
|
// Remove marker from map
|
||||||
|
rulerMarkers[idx].remove();
|
||||||
|
rulerMarkers.splice(idx, 1);
|
||||||
|
rulerPoints.splice(idx, 1);
|
||||||
|
// Recalculate total and update all labels
|
||||||
|
updateRulerLabels();
|
||||||
|
updateRulerLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateRulerLabels() {
|
||||||
|
// Recalculate rulerTotal from scratch and update label elements on each marker
|
||||||
|
rulerTotal = 0;
|
||||||
|
for (let i = 0; i < rulerMarkers.length; i++) {
|
||||||
|
const markerEl = rulerMarkers[i].getElement();
|
||||||
|
const dot = markerEl.querySelector('.ruler-dot');
|
||||||
|
const label = markerEl.querySelector('.ruler-label');
|
||||||
|
const btn = markerEl.querySelector('.ruler-remove-btn');
|
||||||
|
if (i === 0) {
|
||||||
|
if (label) label.textContent = '';
|
||||||
|
} else {
|
||||||
|
const segDist = haversineKm(rulerPoints[i - 1], rulerPoints[i]);
|
||||||
|
rulerTotal += segDist;
|
||||||
|
if (label) {
|
||||||
|
label.textContent = segDist >= 1
|
||||||
|
? segDist.toFixed(1) + ' км'
|
||||||
|
: Math.round(segDist * 1000) + ' м';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update remove button index
|
||||||
|
if (btn) {
|
||||||
|
btn.onclick = (e) => { e.stopPropagation(); removeRulerPoint(i); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update total display
|
||||||
|
const dist = rulerTotal >= 1 ? rulerTotal.toFixed(1) + ' км' : Math.round(rulerTotal * 1000) + ' м';
|
||||||
|
document.getElementById('ruler-dist').textContent = dist;
|
||||||
|
}
|
||||||
|
|
||||||
function addRulerPoint(lngLat) {
|
function addRulerPoint(lngLat) {
|
||||||
const map = window._map;
|
const map = window._map;
|
||||||
const pt = [lngLat.lng, lngLat.lat];
|
const pt = [lngLat.lng, lngLat.lat];
|
||||||
|
const idx = rulerPoints.length;
|
||||||
rulerPoints.push(pt);
|
rulerPoints.push(pt);
|
||||||
if (rulerPoints.length > 1) {
|
|
||||||
rulerTotal += haversineKm(rulerPoints[rulerPoints.length - 2], pt);
|
let segDist = 0;
|
||||||
|
if (idx > 0) {
|
||||||
|
segDist = haversineKm(rulerPoints[idx - 1], pt);
|
||||||
|
rulerTotal += segDist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrapper element for dot + label + remove button
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.style.cssText = 'position:relative;display:flex;flex-direction:column;align-items:center;';
|
||||||
|
|
||||||
|
// Dot
|
||||||
const dot = document.createElement('div');
|
const dot = document.createElement('div');
|
||||||
dot.className = '';
|
dot.className = 'ruler-dot';
|
||||||
dot.style.cssText = 'width:10px;height:10px;background:#0088ff;border:2px solid #fff;border-radius:50%;box-shadow:0 0 4px rgba(0,0,0,0.3);display:block;';
|
dot.style.cssText = 'width:10px;height:10px;background:#0088ff;border:2px solid #fff;border-radius:50%;box-shadow:0 0 4px rgba(0,0,0,0.3);display:block;flex-shrink:0;';
|
||||||
const dotMarker = new maplibregl.Marker({ element: dot, anchor: 'center' })
|
|
||||||
|
// Remove button ×
|
||||||
|
const btn = document.createElement('div');
|
||||||
|
btn.className = 'ruler-remove-btn';
|
||||||
|
btn.textContent = '×';
|
||||||
|
btn.style.cssText = 'position:absolute;top:-10px;right:-10px;width:14px;height:14px;background:rgba(40,40,40,0.85);color:#fff;border-radius:50%;font-size:11px;line-height:14px;text-align:center;cursor:pointer;z-index:10;';
|
||||||
|
btn.onclick = (e) => { e.stopPropagation(); removeRulerPoint(idx); };
|
||||||
|
|
||||||
|
// Distance label below dot
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.className = 'ruler-label';
|
||||||
|
if (idx === 0) {
|
||||||
|
label.textContent = '';
|
||||||
|
} else {
|
||||||
|
label.textContent = segDist >= 1
|
||||||
|
? segDist.toFixed(1) + ' км'
|
||||||
|
: Math.round(segDist * 1000) + ' м';
|
||||||
|
}
|
||||||
|
label.style.cssText = 'margin-top:3px;background:rgba(20,20,20,0.75);color:#fff;font-size:10px;padding:1px 4px;border-radius:3px;white-space:nowrap;pointer-events:none;';
|
||||||
|
|
||||||
|
wrapper.appendChild(dot);
|
||||||
|
wrapper.appendChild(btn);
|
||||||
|
wrapper.appendChild(label);
|
||||||
|
|
||||||
|
const dotMarker = new maplibregl.Marker({ element: wrapper, anchor: 'top' })
|
||||||
.setLngLat([lngLat.lng, lngLat.lat])
|
.setLngLat([lngLat.lng, lngLat.lat])
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
rulerMarkers.push(dotMarker);
|
rulerMarkers.push(dotMarker);
|
||||||
|
|||||||
Reference in New Issue
Block a user