diff options
Diffstat (limited to 'modern/src/map/switcher/switcher.js')
-rw-r--r-- | modern/src/map/switcher/switcher.js | 79 |
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 0000000..ff9fbe9 --- /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'; + } + } +} |