diff --git a/tasks/enduro-trails/prototype/static/app.js b/tasks/enduro-trails/prototype/static/app.js index d083d7b..1b8d69e 100644 --- a/tasks/enduro-trails/prototype/static/app.js +++ b/tasks/enduro-trails/prototype/static/app.js @@ -1675,17 +1675,91 @@ function updateRulerLine() { 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) { const map = window._map; const pt = [lngLat.lng, lngLat.lat]; + const idx = rulerPoints.length; 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'); - dot.className = ''; - 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;'; - const dotMarker = new maplibregl.Marker({ element: dot, anchor: 'center' }) + 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;flex-shrink:0;'; + + // 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]) .addTo(map); rulerMarkers.push(dotMarker);