forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmapChrome.ts
More file actions
60 lines (51 loc) · 2.08 KB
/
Copy pathmapChrome.ts
File metadata and controls
60 lines (51 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// The map's own MapLibre controls: compass, locate, scale bar.
//
// Placement follows WIREFRAMES.md's one interaction rule for this screen -
// everything tapped mid-walk sits in the lower third, everything read but not
// touched sits above. So compass and locate stack bottom-right in the thumb
// zone, and the scale bar sits bottom-left, read but never pressed.
//
// Zoom buttons are web-only on purpose. Pinch already covers zoom on a phone,
// and the thumb zone is the most reachable real estate on the screen - spending
// it on the least necessary control is a bad trade when the user is walking.
import { GeolocateControl, NavigationControl, ScaleControl } from 'maplibre-gl'
import type { Map as MapLibreMap } from 'maplibre-gl'
export type ScaleUnits = 'imperial' | 'metric'
export interface MapChromeOptions {
/** Web only - touch platforms rely on pinch (see note above). */
showZoomButtons: boolean
units: ScaleUnits
}
/** WIREFRAMES.md: scale bar is 64px wide. */
const SCALE_MAX_WIDTH = 64
/**
* Adds the map's controls and returns a detach function that removes every one
* of them - so a remount cannot leave a second set stacked on the first.
*/
export function attachMapChrome(
map: MapLibreMap,
{ showZoomButtons, units }: MapChromeOptions,
): () => void {
const compass = new NavigationControl({
showZoom: showZoomButtons,
// Always present: tapping it resets north-up, which is the way back when
// a rotated map has stopped matching the paper picture in someone's head.
showCompass: true,
visualizePitch: false,
})
const locate = new GeolocateControl({
// Continuous, not a single fix - the blue dot has to follow the walk.
trackUserLocation: true,
showAccuracyCircle: true,
positionOptions: { enableHighAccuracy: true },
})
const scale = new ScaleControl({ unit: units, maxWidth: SCALE_MAX_WIDTH })
map.addControl(compass, 'bottom-right')
map.addControl(locate, 'bottom-right')
map.addControl(scale, 'bottom-left')
return () => {
for (const control of [compass, locate, scale]) {
map.removeControl(control)
}
}
}