Skip to content

Commit 16f0939

Browse files
committed
fix(map): stop reprojecting routes on every pan frame
Both the index and route-detail maps bound adjustTrailStrokes to 'move', reprojecting every route polyline vertex per frame. Pan doesn't change the SVG scale or stroke width and Leaflet translates the renderer pane natively, so the per-frame reprojection was wasted work that made touch panning crawl when many routes were visible. Gate it on an actual zoom change; zoom gestures still step zoom per frame, so constant stroke width is preserved.
1 parent 3a74251 commit 16f0939

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ All notable changes to Ferd are recorded here. The format follows [Keep a Change
3232
- The navigation tabs, Add, and Menu buttons use one larger size at every width instead of shrinking on narrow screens, and the space above page content is tighter and no longer jumps when the window crosses a breakpoint.
3333

3434
### Fixed
35+
- Panning a map with routes visible is no longer sluggish on touch devices (and smoother on desktop): route geometry is re-projected only when the zoom changes, so a pure pan falls back to the map's native cheap translate instead of reprojecting every route vertex on each frame.
3536
- Index map: place pins no longer vanish on the right side of the map after the window is widened. The marker canvas now resizes with the map instead of holding its initial width and clipping pins past it.
3637
- Opening a large multi-segment route no longer flashes and re-fits the map a second or two in: the elevation area reserves its height up front instead of expanding once the GPX finishes parsing.
3738
- Very large routes (continental routes with tens of thousands of points, whether one track or many) open and pan smoothly in the detail view instead of stalling: map geometry thins to the current zoom, elevation profiles are sampled down, and route lines hold a constant width through zoom.

index.html

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5208,6 +5208,27 @@
52085208
}
52095209
}
52105210

5211+
// Bind stroke-fixup to map motion. Pan-only 'move' frames don't change
5212+
// zoom, so the SVG scale and stroke widths are unchanged and Leaflet
5213+
// translates the renderer pane natively - reprojecting every route vertex
5214+
// per pan frame is wasted work that makes touch panning crawl when many
5215+
// routes are visible. Only reproject when the zoom actually changed (zoom
5216+
// gestures: desktop smooth-wheel, mobile pinch, both step zoom per frame).
5217+
// A trailing pass on zoomend/moveend guarantees correctness at rest.
5218+
function bindTrailStrokeMotion(map) {
5219+
let lastZoom = map.getZoom();
5220+
map.on('move', function () {
5221+
const z = map.getZoom();
5222+
if (z === lastZoom) return;
5223+
lastZoom = z;
5224+
adjustTrailStrokes();
5225+
});
5226+
map.on('zoomend moveend', function () {
5227+
lastZoom = map.getZoom();
5228+
adjustTrailStrokes();
5229+
});
5230+
}
5231+
52115232
// Index-map route highlight. Clicking a route flags it as selected: it
52125233
// fattens, goes fully opaque, and jumps to the front while the rest dim
52135234
// back, so it stands out where several routes overlap. Style-based, so it
@@ -5595,8 +5616,7 @@
55955616
// by the time we run, the SVG renderer has already applied its new
55965617
// CSS scale transform - we read the freshest value to counter-scale
55975618
// against. Also covers pan-only frames.
5598-
map.on('move', adjustTrailStrokes);
5599-
map.on('zoomend moveend', adjustTrailStrokes);
5619+
bindTrailStrokeMotion(map);
56005620
map.on('zoomanim', function() {
56015621
const start = performance.now();
56025622
const tick = () => {
@@ -8810,8 +8830,7 @@
88108830
// by the time we run, the SVG renderer has already applied its new
88118831
// CSS scale transform - we read the freshest value to counter-scale
88128832
// against. Also covers pan-only frames.
8813-
map.on('move', adjustTrailStrokes);
8814-
map.on('zoomend moveend', adjustTrailStrokes);
8833+
bindTrailStrokeMotion(map);
88158834
map.on('zoomanim', function() {
88168835
const start = performance.now();
88178836
const tick = () => {

0 commit comments

Comments
 (0)