aboutsummaryrefslogtreecommitdiff
path: root/modern/src/map/switcher
diff options
context:
space:
mode:
Diffstat (limited to 'modern/src/map/switcher')
-rw-r--r--modern/src/map/switcher/switcher.css40
-rw-r--r--modern/src/map/switcher/switcher.js79
2 files changed, 119 insertions, 0 deletions
diff --git a/modern/src/map/switcher/switcher.css b/modern/src/map/switcher/switcher.css
new file mode 100644
index 00000000..6c8fdb4e
--- /dev/null
+++ b/modern/src/map/switcher/switcher.css
@@ -0,0 +1,40 @@
+.mapboxgl-style-list
+{
+ display: none;
+}
+
+.mapboxgl-ctrl-group .mapboxgl-style-list button
+{
+ background: none;
+ border: none;
+ cursor: pointer;
+ display: block;
+ font-size: 14px;
+ padding: 8px 8px 6px;
+ text-align: right;
+ width: 100%;
+ height: auto;
+}
+
+.mapboxgl-style-list button.active
+{
+ font-weight: bold;
+}
+
+.mapboxgl-style-list button:hover
+{
+ background-color: rgba(0, 0, 0, 0.05);
+}
+
+.mapboxgl-style-list button + button
+{
+ border-top: 1px solid #ddd;
+}
+
+.mapboxgl-style-switcher
+{
+ background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNTQuODQ5cHgiIGhlaWdodD0iNTQuODQ5cHgiIHZpZXdCb3g9IjAgMCA1NC44NDkgNTQuODQ5IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1NC44NDkgNTQuODQ5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PGc+PGc+PHBhdGggZD0iTTU0LjQ5NywzOS42MTRsLTEwLjM2My00LjQ5bC0xNC45MTcsNS45NjhjLTAuNTM3LDAuMjE0LTEuMTY1LDAuMzE5LTEuNzkzLDAuMzE5Yy0wLjYyNywwLTEuMjU0LTAuMTA0LTEuNzktMC4zMThsLTE0LjkyMS01Ljk2OEwwLjM1MSwzOS42MTRjLTAuNDcyLDAuMjAzLTAuNDY3LDAuNTI0LDAuMDEsMC43MTZMMjYuNTYsNTAuODFjMC40NzcsMC4xOTEsMS4yNTEsMC4xOTEsMS43MjksMEw1NC40ODgsNDAuMzNDNTQuOTY0LDQwLjEzOSw1NC45NjksMzkuODE3LDU0LjQ5NywzOS42MTR6Ii8+PHBhdGggZD0iTTU0LjQ5NywyNy41MTJsLTEwLjM2NC00LjQ5MWwtMTQuOTE2LDUuOTY2Yy0wLjUzNiwwLjIxNS0xLjE2NSwwLjMyMS0xLjc5MiwwLjMyMWMtMC42MjgsMC0xLjI1Ni0wLjEwNi0xLjc5My0wLjMyMWwtMTQuOTE4LTUuOTY2TDAuMzUxLDI3LjUxMmMtMC40NzIsMC4yMDMtMC40NjcsMC41MjMsMC4wMSwwLjcxNkwyNi41NiwzOC43MDZjMC40NzcsMC4xOSwxLjI1MSwwLjE5LDEuNzI5LDBsMjYuMTk5LTEwLjQ3OUM1NC45NjQsMjguMDM2LDU0Ljk2OSwyNy43MTYsNTQuNDk3LDI3LjUxMnoiLz48cGF0aCBkPSJNMC4zNjEsMTYuMTI1bDEzLjY2Miw1LjQ2NWwxMi41MzcsNS4wMTVjMC40NzcsMC4xOTEsMS4yNTEsMC4xOTEsMS43MjksMGwxMi41NDEtNS4wMTZsMTMuNjU4LTUuNDYzYzAuNDc3LTAuMTkxLDAuNDgtMC41MTEsMC4wMS0wLjcxNkwyOC4yNzcsNC4wNDhjLTAuNDcxLTAuMjA0LTEuMjM2LTAuMjA0LTEuNzA4LDBMMC4zNTEsMTUuNDFDLTAuMTIxLDE1LjYxNC0wLjExNiwxNS45MzUsMC4zNjEsMTYuMTI1eiIvPjwvZz48L2c+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvc3ZnPg==);
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 70%;
+}
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';
+ }
+ }
+}