aboutsummaryrefslogtreecommitdiff
path: root/modern/src/map/switcher/switcher.js
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2020-11-01 15:37:23 -0800
committerAnton Tananaev <anton.tananaev@gmail.com>2020-11-01 15:37:23 -0800
commite0b977f7f50b4174382df7787f63d58dac3e6ed8 (patch)
tree8627f65501afac3f6518da29b9358b81f91f97fb /modern/src/map/switcher/switcher.js
parent76ef2b38fac5c58264921479b0e7d19115bb9c7d (diff)
downloadtrackermap-web-e0b977f7f50b4174382df7787f63d58dac3e6ed8.tar.gz
trackermap-web-e0b977f7f50b4174382df7787f63d58dac3e6ed8.tar.bz2
trackermap-web-e0b977f7f50b4174382df7787f63d58dac3e6ed8.zip
Implement map switching
Diffstat (limited to 'modern/src/map/switcher/switcher.js')
-rw-r--r--modern/src/map/switcher/switcher.js79
1 files changed, 79 insertions, 0 deletions
diff --git a/modern/src/map/switcher/switcher.js b/modern/src/map/switcher/switcher.js
new file mode 100644
index 00000000..ff9fbe97
--- /dev/null
+++ b/modern/src/map/switcher/switcher.js
@@ -0,0 +1,79 @@
+export class SwitcherControl {
+
+ constructor(styles, defaultStyle, beforeSwitch, afterSwitch) {
+ this.styles = styles;
+ this.defaultStyle = defaultStyle;
+ this.beforeSwitch = beforeSwitch;
+ this.afterSwitch = afterSwitch;
+ this.onDocumentClick = this.onDocumentClick.bind(this);
+ }
+
+ getDefaultPosition() {
+ return 'top-right';
+ }
+
+ onAdd(map) {
+ this.map = map;
+ this.controlContainer = document.createElement('div');
+ this.controlContainer.classList.add('mapboxgl-ctrl');
+ this.controlContainer.classList.add('mapboxgl-ctrl-group');
+ this.mapStyleContainer = document.createElement('div');
+ this.styleButton = document.createElement('button');
+ this.styleButton.type = 'button';
+ this.mapStyleContainer.classList.add('mapboxgl-style-list');
+ for (const style of this.styles) {
+ const styleElement = document.createElement('button');
+ styleElement.type = 'button';
+ styleElement.innerText = style.title;
+ styleElement.classList.add(style.title.replace(/[^a-z0-9-]/gi, '_'));
+ styleElement.dataset.uri = JSON.stringify(style.uri);
+ styleElement.addEventListener('click', event => {
+ const srcElement = event.srcElement;
+ if (srcElement.classList.contains('active')) {
+ return;
+ }
+ this.beforeSwitch();
+ this.map.setStyle(JSON.parse(srcElement.dataset.uri));
+ this.afterSwitch();
+ this.mapStyleContainer.style.display = 'none';
+ this.styleButton.style.display = 'block';
+ const elms = this.mapStyleContainer.getElementsByClassName('active');
+ while (elms[0]) {
+ elms[0].classList.remove('active');
+ }
+ srcElement.classList.add('active');
+ });
+ if (style.title === this.defaultStyle) {
+ styleElement.classList.add('active');
+ }
+ this.mapStyleContainer.appendChild(styleElement);
+ }
+ this.styleButton.classList.add('mapboxgl-ctrl-icon');
+ this.styleButton.classList.add('mapboxgl-style-switcher');
+ this.styleButton.addEventListener('click', () => {
+ this.styleButton.style.display = 'none';
+ this.mapStyleContainer.style.display = 'block';
+ });
+ document.addEventListener('click', this.onDocumentClick);
+ this.controlContainer.appendChild(this.styleButton);
+ this.controlContainer.appendChild(this.mapStyleContainer);
+ return this.controlContainer;
+ }
+
+ onRemove() {
+ if (!this.controlContainer || !this.controlContainer.parentNode || !this.map || !this.styleButton) {
+ return;
+ }
+ this.styleButton.removeEventListener('click', this.onDocumentClick);
+ this.controlContainer.parentNode.removeChild(this.controlContainer);
+ document.removeEventListener('click', this.onDocumentClick);
+ this.map = undefined;
+ }
+
+ onDocumentClick(event) {
+ if (this.controlContainer && !this.controlContainer.contains(event.target) && this.mapStyleContainer && this.styleButton) {
+ this.mapStyleContainer.style.display = 'none';
+ this.styleButton.style.display = 'block';
+ }
+ }
+}