Skip to content

Commit 7d2851f

Browse files
committed
Add ability to store the sample state in the URL and navigate directly.
Also add back-button support.
1 parent 64bed5b commit 7d2851f

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

OpenMapSamplesControl.js

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ export default class SampleControl {
1212
constructor (options = {}) {
1313
this.samples = {};
1414
this.options = options;
15+
if (this.options['permalinks']) {
16+
this.permalinks = true;
17+
}
18+
else {
19+
this.permalinks = false;
20+
}
1521
}
1622

1723
addSample(sample) {
@@ -63,6 +69,12 @@ export default class SampleControl {
6369

6470
this.hideControls();
6571

72+
// Try loading our sampledata if specified in the url.
73+
if (this.permalinks) {
74+
setTimeout(this.setStateFromUrl.bind(this), 2000);
75+
window.addEventListener("popstate", this.setStateFromUrl.bind(this));
76+
}
77+
6678
return this._container;
6779
}
6880

@@ -91,6 +103,68 @@ export default class SampleControl {
91103
this._controls.style.display = 'none';
92104
}
93105

106+
updatePermalink() {
107+
if (this.permalinks) {
108+
var url = new URL(window.location.href);
109+
// Add/remove the active sample state.
110+
if (this.getActiveSampleId()) {
111+
url.searchParams.set('omss', this.getActiveSampleId());
112+
url.searchParams.set('omsv', this.getActiveSampleVariantId());
113+
} else {
114+
url.searchParams.delete('omss');
115+
url.searchParams.delete('omsv');
116+
}
117+
118+
var state = {
119+
'hash': url.hash,
120+
'omss':this.getActiveSampleId(),
121+
'omsv': this.getActiveSampleVariantId(),
122+
};
123+
window.history.pushState(state, 'oms', url);
124+
}
125+
}
126+
127+
setStateFromUrl() {
128+
if (this.permalinks) {
129+
const url = new URL(window.location.href);
130+
131+
// Store incoming zoom and center for resetting after load of a sample.
132+
var zoom = null;
133+
var center = null;
134+
const hash = window.location.hash.replace('#', '');
135+
const parts = hash.split('/');
136+
if (parts.length === 3 || parts.length === 4) {
137+
zoom = parseFloat(parts[0]);
138+
center = [
139+
parseFloat(parts[2]),
140+
parseFloat(parts[1]),
141+
];
142+
}
143+
144+
const sampleId = url.searchParams.get('omss');
145+
if (sampleId) {
146+
this.showControls();
147+
this.setActiveSampleId(sampleId);
148+
149+
const sampleVariantId = url.searchParams.get('omsv');
150+
if (sampleVariantId) {
151+
this.setActiveSampleVariantId(sampleVariantId);
152+
}
153+
} else if (this.getActiveSampleId()) {
154+
this.clearDisplayedSample();
155+
}
156+
157+
158+
// Reset zoom from URL.
159+
if (sampleId && zoom) {
160+
this._map.setZoom(zoom);
161+
}
162+
if (sampleId && center) {
163+
this._map.setCenter(center);
164+
}
165+
}
166+
}
167+
94168
initializeSamplesMenu() {
95169
this._samplesMenu = document.createElement('select');
96170
this._samplesMenu.className = 'openmapsamples-control-samples-menu';
@@ -110,13 +184,43 @@ export default class SampleControl {
110184
this._samplesMenu.onchange = this.chooseSample.bind(this);
111185
}
112186

187+
getActiveSampleId() {
188+
if (this._samplesMenu) {
189+
return this._samplesMenu.value;
190+
} else {
191+
return null;
192+
}
193+
}
194+
195+
getActiveSampleVariantId() {
196+
if (this._variantSelect) {
197+
return this._variantSelect.value;
198+
} else {
199+
return null;
200+
}
201+
}
202+
203+
setActiveSampleId(id) {
204+
this._samplesMenu.value = id;
205+
this.chooseSample();
206+
}
207+
208+
setActiveSampleVariantId(id) {
209+
if (this._variantSelect) {
210+
this._variantSelect.value = id;
211+
this.changeVariant(this.samples[this.getActiveSampleId()]);
212+
}
213+
}
214+
113215
chooseSample() {
114-
if (this._samplesMenu.value == '') {
216+
if (this.getActiveSampleId() == '') {
115217
this.clearDisplayedSample();
116218
this._chooseOrClear.textContent = "Choose a Sample...";
219+
this.updatePermalink();
117220
} else {
118-
this.displaySample(this.samples[this._samplesMenu.value]);
221+
this.displaySample(this.samples[this.getActiveSampleId()]);
119222
this._chooseOrClear.textContent = "Clear...";
223+
this.updatePermalink();
120224
}
121225
}
122226

@@ -257,6 +361,7 @@ export default class SampleControl {
257361
// Jump to our starting zoom/location.
258362
this._map.setCenter(sample.getZoomVariantCenter(this.variant));
259363
this._map.setZoom(this.variant);
364+
this.updatePermalink();
260365
}
261366
}
262367

demo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async function main() {
2626
m.setStyle(style);
2727

2828
// Add our sample data.
29-
let sampleControl = new SampleControl();
29+
let sampleControl = new SampleControl({'permalinks': true});
3030

3131
OpenMapTilesSamples.forEach((sample, i) => {
3232
sampleControl.addSample(sample);

0 commit comments

Comments
 (0)