This repository has been archived by the owner on Sep 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.js
109 lines (89 loc) · 3.02 KB
/
index.js
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
'use strict';
import xtend from 'xtend';
import bbox from '@turf/bbox';
import debounce from 'lodash/debounce';
export default class MapboxAccessibility {
constructor(options) {
const defaultOptions = {
width: 24,
height: 24
};
if (!options && !options.layers) {
throw new Error('An array of layers is required');
}
if (!options && !options.accessibleLabelProperty) {
throw new Error('a valid accessibleLabelProperty is required');
}
this.options = xtend(defaultOptions, options);
}
clearMarkers = () => {
if (this.features) {
this.features.forEach(feature => {
if (feature.marker) {
this.map.getCanvasContainer().removeChild(feature.marker);
delete feature.marker;
}
});
}
}
queryFeatures = () => {
this._debouncedQueryFeatures.cancel();
this.clearMarkers();
this.features = this.map.queryRenderedFeatures({ layers: this.options.layers });
this.features.map((feature) => {
let { width, height } = this.options;
const label = feature.properties[this.options.accessibleLabelProperty];
feature.marker = document.createElement('button');
feature.marker.setAttribute('aria-label', label);
feature.marker.setAttribute('title', label);
feature.marker.setAttribute('tabindex', 0);
feature.marker.style.display = 'block';
let position;
if (feature.geometry.type === 'Point') {
position = this.map.project(feature.geometry.coordinates);
} else {
const featureBbox = bbox(feature);
const bl = this.map.project([featureBbox[0], featureBbox[1]]);
const tr = this.map.project([featureBbox[2], featureBbox[3]]);
width = Math.abs(tr.x - bl.x);
height = Math.abs(tr.y - bl.y);
position = {
x: ((tr.x + bl.x) / 2),
y: ((tr.y + bl.y) / 2),
};
}
feature.marker.style.width = `${width}px`;
feature.marker.style.height = `${height}px`;
feature.marker.style.transform = `translate(-50%, -50%) translate(${position.x}px, ${position.y}px)`;
feature.marker.className = 'mapboxgl-accessibility-marker';
this.map.getCanvasContainer().appendChild(feature.marker);
return feature;
});
}
_movestart = () => {
this._debouncedQueryFeatures.cancel();
this.clearMarkers();
}
_render = () => {
if (!this.map.isMoving()) {
this._debouncedQueryFeatures();
}
}
onAdd(map) {
this.map = map;
this._debouncedQueryFeatures = debounce(this.queryFeatures, 100);
this.map.on('movestart', this._movestart);
this.map.on('moveend', this._render);
this.map.on('render', this._render);
this.container = document.createElement('div');
return this.container;
}
onRemove() {
this.container.parentNode.removeChild(this.container);
this.map.off('movestart', this._movestart);
this.map.off('moveend', this._render);
this.map.off('render', this._render);
this._debouncedQueryFeatures.cancel();
delete this.map;
}
}