map: dynamische startzoom / highlightzoom per set en per item #116

Closed
opened 2026-04-22 09:05:46 +02:00 by Ghost · 1 comment
Ghost commented 2026-04-22 09:05:46 +02:00 (Migrated from codeberg.org)

Symptoom

Set 5.4 Provincies (en waarschijnlijk meer NL-sets) opent met een zoomlevel dat NL heel klein laat zien — heel NW-Europa staat in beeld (UK, Denemarken, halve Duitsland), terwijl de provincie-vraag echt om een NL-scope vraagt.

screenshot

Root cause

Twee zoom-regels strijden met elkaar:

  1. Start-fit: map.fitBounds(NL_BOUNDS, { padding: [4,4], maxZoom: 9 }) na applyVisibility('quiz') — die kiest netjes zoom 8-9.
  2. Per-item highlight: polygonTypes.province.highlightZoom = 6. Zodra de eerste provincie wordt gehighlight (synchroon in renderQuestion() dat ná de start-fit draait), trekt Leaflet de kaart terug naar zoom ~6 omdat dat de "cap" is voor province-items.

Zelfde mechaniek speelt bij country (highlightZoom: 5) en water (highlightZoom: 10). Omdat een item-bounds heel klein kan zijn (Utrecht) of groot (Rusland), is één vaste `highlightZoom` per type geen goede proxy voor "hoe ver uit moet ik zoomen".

Extra complicatie (#102 gevolg)

Sinds v2.22.0 is de quiz-kaart flex:1 (fit-to-viewport). De kaart-hoogte varieert dus met viewport-hoogte, maar de `highlightZoom` + `padding` zijn statisch. Op korte laptops lijkt de provincie nóg kleiner.

Voorstel — opties

Optie A — adaptieve maxZoom op basis van item-bounds

function fitWithPadding(bounds, padding=[60,60]) {
  // Geen maxZoom: laat Leaflet de optimale zoom berekenen die de
  // bounds + padding in de huidige container past. Cap absoluut op 12
  // zodat een stip op de kaart niet naar straatniveau zoomt.
  const optimal = map.getBoundsZoom(bounds, false, L.point(padding));
  return map.fitBounds(bounds, { padding, maxZoom: Math.min(optimal, 12) });
}

Voordeel: geen per-type constantes meer. Kleine provincies zoomen in, grote landen uit. Schaalt automatisch met viewport.

Optie B — per-item hint via item.zoom (override)

Voor uitzonderingen (bv. Rusland krijgt een specifieke zoom: 3 hint omdat je anders door de Pacific scroll).

Combinatie: A als default, B als opt-in override.

Scope

  • setHighlightPolygon → vervang harde highlightZoom door getBoundsZoom-berekening.
  • Test alle vier polygon-types (province, country, water, region).
  • Baseline-screenshots voor visual regression (Playwright toHaveScreenshot) — op zijn minst voor set 5.4, 7.1, 7.3, 8.1.
  • NL_BOUNDS initial-fit: mag blijven maar padding herzien zodat NL strak in beeld staat, niet met zeeën eromheen.

Out of scope

  • Pan-animatie tussen vragen (apart gedrag).
  • Bounds-herberekening op window-resize (edge case).

Prior art in repo

  • polygonTypes.province.skipFit voor fuzzy/peak shapes — precedent voor per-shape branching.
  • set.fitOnStart + bounds — precedent voor per-set-override.
## Symptoom Set 5.4 Provincies (en waarschijnlijk meer NL-sets) opent met een zoomlevel dat NL heel klein laat zien — heel NW-Europa staat in beeld (UK, Denemarken, halve Duitsland), terwijl de provincie-vraag echt om een NL-scope vraagt. ![screenshot](https://user-images.githubusercontent.com/placeholder) <!-- vervang bij oppakken --> ## Root cause Twee zoom-regels strijden met elkaar: 1. **Start-fit**: `map.fitBounds(NL_BOUNDS, { padding: [4,4], maxZoom: 9 })` na `applyVisibility('quiz')` — die kiest netjes zoom 8-9. 2. **Per-item highlight**: `polygonTypes.province.highlightZoom = 6`. Zodra de eerste provincie wordt gehighlight (synchroon in `renderQuestion()` dat ná de start-fit draait), trekt Leaflet de kaart terug naar zoom ~6 omdat dat de \"cap\" is voor province-items. Zelfde mechaniek speelt bij `country` (`highlightZoom: 5`) en `water` (`highlightZoom: 10`). Omdat een item-bounds heel klein kan zijn (Utrecht) of groot (Rusland), is één vaste \`highlightZoom\` per type geen goede proxy voor \"hoe ver uit moet ik zoomen\". ## Extra complicatie (#102 gevolg) Sinds v2.22.0 is de quiz-kaart `flex:1` (fit-to-viewport). De kaart-hoogte varieert dus met viewport-hoogte, maar de \`highlightZoom\` + \`padding\` zijn statisch. Op korte laptops lijkt de provincie nóg kleiner. ## Voorstel — opties **Optie A — adaptieve maxZoom op basis van item-bounds** ```js function fitWithPadding(bounds, padding=[60,60]) { // Geen maxZoom: laat Leaflet de optimale zoom berekenen die de // bounds + padding in de huidige container past. Cap absoluut op 12 // zodat een stip op de kaart niet naar straatniveau zoomt. const optimal = map.getBoundsZoom(bounds, false, L.point(padding)); return map.fitBounds(bounds, { padding, maxZoom: Math.min(optimal, 12) }); } ``` Voordeel: geen per-type constantes meer. Kleine provincies zoomen in, grote landen uit. Schaalt automatisch met viewport. **Optie B — per-item hint via `item.zoom` (override)** Voor uitzonderingen (bv. Rusland krijgt een specifieke `zoom: 3` hint omdat je anders door de Pacific scroll). **Combinatie**: A als default, B als opt-in override. ## Scope - [ ] `setHighlightPolygon` → vervang harde `highlightZoom` door `getBoundsZoom`-berekening. - [ ] Test alle vier polygon-types (province, country, water, region). - [ ] Baseline-screenshots voor visual regression (Playwright `toHaveScreenshot`) — op zijn minst voor set 5.4, 7.1, 7.3, 8.1. - [ ] `NL_BOUNDS` initial-fit: mag blijven maar padding herzien zodat NL strak in beeld staat, niet met zeeën eromheen. ## Out of scope - Pan-animatie tussen vragen (apart gedrag). - Bounds-herberekening op window-resize (edge case). ## Prior art in repo - `polygonTypes.province.skipFit` voor fuzzy/peak shapes — precedent voor per-shape branching. - `set.fitOnStart` + `bounds` — precedent voor per-set-override.
Ghost commented 2026-04-22 10:16:06 +02:00 (Migrated from codeberg.org)

Fixed in v2.24.1 — highlightZoom-cap in polygonTypes verruimd van 6/10/5 naar 12 voor alle polygon-types (province/water/country). fitBounds berekent nu zelf de optimale zoom uit item-bounds + padding, 12 dient als safety-cap om micro-items (toekomstige kleine eilanden) niet naar straatniveau te laten schieten.

Fixed in v2.24.1 — highlightZoom-cap in polygonTypes verruimd van 6/10/5 naar 12 voor alle polygon-types (province/water/country). fitBounds berekent nu zelf de optimale zoom uit item-bounds + padding, 12 dient als safety-cap om micro-items (toekomstige kleine eilanden) niet naar straatniveau te laten schieten.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jelmer/topoquiz#116
No description provided.