]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/history-changesets-layer.js
Move changeset colors to css
[rails.git] / app / assets / javascripts / index / history-changesets-layer.js
1 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
2   _changesets: new Map,
3
4   _getChangesetStyle: function ({ isHighlighted }) {
5     let className = "changeset-in-sidebar-viewport";
6
7     if (isHighlighted) {
8       className += " changeset-highlighted";
9     }
10
11     return {
12       weight: isHighlighted ? 3 : 2,
13       color: "var(--changeset-border-color)",
14       fillColor: "var(--changeset-fill-color)",
15       fillOpacity: isHighlighted ? 0.3 : 0,
16       className
17     };
18   },
19
20   _updateChangesetStyle: function (changeset) {
21     const rect = this.getLayer(changeset.id);
22     if (!rect) return;
23
24     const style = this._getChangesetStyle(changeset);
25     rect.setStyle(style);
26     // setStyle doesn't update css classes: https://github.com/leaflet/leaflet/issues/2662
27     rect._path.classList.value = style.className;
28     rect._path.classList.add("leaflet-interactive");
29   },
30
31   updateChangesets: function (map, changesets) {
32     this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
33     this.updateChangesetShapes(map);
34   },
35
36   updateChangesetShapes: function (map) {
37     this.clearLayers();
38
39     for (const changeset of this._changesets.values()) {
40       const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
41             topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
42             width = topRight.x - bottomLeft.x,
43             height = bottomLeft.y - topRight.y,
44             minSize = 20; // Min width/height of changeset in pixels
45
46       if (width < minSize) {
47         bottomLeft.x -= ((minSize - width) / 2);
48         topRight.x += ((minSize - width) / 2);
49       }
50
51       if (height < minSize) {
52         bottomLeft.y += ((minSize - height) / 2);
53         topRight.y -= ((minSize - height) / 2);
54       }
55
56       changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
57                                         map.unproject(topRight));
58     }
59
60     const changesetEntries = [...this._changesets];
61     changesetEntries.sort(([, a], [, b]) => {
62       return b.bounds.getSize() - a.bounds.getSize();
63     });
64     this._changesets = new Map(changesetEntries);
65
66     this.updateChangesetLocations(map);
67
68     for (const changeset of this._changesets.values()) {
69       delete changeset.isHighlighted;
70       const rect = L.rectangle(changeset.bounds, this._getChangesetStyle(changeset));
71       rect.id = changeset.id;
72       rect.addTo(this);
73     }
74   },
75
76   updateChangesetLocations: function (map) {
77     const mapCenterLng = map.getCenter().lng;
78
79     for (const changeset of this._changesets.values()) {
80       const changesetSouthWest = changeset.bounds.getSouthWest();
81       const changesetNorthEast = changeset.bounds.getNorthEast();
82       const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
83       const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
84
85       if (shiftInWorldCircumferences) {
86         changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
87         changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
88
89         this.getLayer(changeset.id)?.setBounds(changeset.bounds);
90       }
91     }
92   },
93
94   toggleChangesetHighlight: function (id, state) {
95     const changeset = this._changesets.get(id);
96     if (!changeset) return;
97
98     changeset.isHighlighted = state;
99     this._updateChangesetStyle(changeset);
100   },
101
102   getLayerId: function (layer) {
103     return layer.id;
104   }
105 });