aboutsummaryrefslogtreecommitdiff
path: root/modern/src/map/switcher/switcher.js
blob: 60a5eff7fc9c0009f63a0235dcb3f4fab4acf17c (plain)
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
110
111
112
export class SwitcherControl {

  constructor(onBeforeSwitch, onSwitch, onAfterSwitch) {
    this.onBeforeSwitch = onBeforeSwitch;
    this.onSwitch = onSwitch;
    this.onAfterSwitch = onAfterSwitch;
    this.onDocumentClick = this.onDocumentClick.bind(this);
    this.styles = [];
    this.currentStyle = null;
  }

  getDefaultPosition() {
    return 'top-right';
  }

  updateStyles(updatedStyles, defaultStyle) {
    this.styles = updatedStyles;

    const selectedStyle = this.currentStyle || defaultStyle;

    while (this.mapStyleContainer.firstChild) {
      this.mapStyleContainer.removeChild(this.mapStyleContainer.firstChild);
    }

    let selectedStyleElement;

    for (const style of this.styles) {
      const styleElement = document.createElement('button');
      styleElement.type = 'button';
      styleElement.innerText = style.title;
      styleElement.dataset.id = style.id;
      styleElement.dataset.uri = JSON.stringify(style.uri);
      styleElement.addEventListener('click', (event) => {
        const { target } = event;
        if (!target.classList.contains('active')) {
          this.onSelectStyle(target);
        }
      });
      if (style.id === selectedStyle) {
        selectedStyleElement = styleElement;
        styleElement.classList.add('active');
      }
      this.mapStyleContainer.appendChild(styleElement);
    }

    if (this.currentStyle !== selectedStyle) {
      this.onSelectStyle(selectedStyleElement);
      this.currentStyle = selectedStyle;
    }
  }

  onSelectStyle(target) {
    this.onBeforeSwitch();

    this.map.setStyle(JSON.parse(target.dataset.uri), {
      diff: false,
    });

    this.onSwitch(target.dataset.id);

    this.mapStyleContainer.style.display = 'none';
    this.styleButton.style.display = 'block';

    const elements = this.mapStyleContainer.getElementsByClassName('active');
    while (elements[0]) {
      elements[0].classList.remove('active');
    }
    target.classList.add('active');

    this.currentStyle = target.dataset.id;

    this.onAfterSwitch();
  }

  onAdd(map) {
    this.map = map;
    this.controlContainer = document.createElement('div');
    this.controlContainer.classList.add('maplibregl-ctrl');
    this.controlContainer.classList.add('maplibregl-ctrl-group');
    this.mapStyleContainer = document.createElement('div');
    this.styleButton = document.createElement('button');
    this.styleButton.type = 'button';
    this.mapStyleContainer.classList.add('maplibregl-style-list');
    this.styleButton.classList.add('maplibregl-ctrl-icon');
    this.styleButton.classList.add('maplibregl-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';
    }
  }
}