From 519bc8efdb171d9e433fd80438bb05dc1bb9b50f Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sat, 7 Dec 2024 18:53:56 +0100 Subject: [PATCH] generate theme-specific style JSON files --- proxy/index.html | 6 +-- proxy/js/styles.mjs | 16 +++++--- proxy/js/ui.js | 93 ++++++++++++++++++--------------------------- 3 files changed, 51 insertions(+), 64 deletions(-) diff --git a/proxy/index.html b/proxy/index.html index 1f5ce414..a94d19c7 100644 --- a/proxy/index.html +++ b/proxy/index.html @@ -137,15 +137,15 @@
- +
- +
- +
diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 70cc478c..4d49d364 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -19,6 +19,10 @@ const knownStyles = [ 'loading_gauge', 'track_class', ]; +const knownThemes = [ + 'light', + 'dark', +]; const globalMinZoom = 1; const glodalMaxZoom = 20; @@ -3655,7 +3659,7 @@ const layers = { ], }; -const makeStyle = selectedStyle => ({ +const makeStyle = (selectedStyle, theme) => ({ center: [12.55, 51.14], // default zoom: 3.75, // default glyphs: `${origin}/font/{fontstack}/{range}`, @@ -5273,8 +5277,8 @@ const layerVisibleAtZoom = (zoom) => const legendPointToMapPoint = (zoom, [x, y]) => [x * coordinateFactor(zoom), y * coordinateFactor(zoom)] -function makeLegendStyle(style) { - const sourceStyle = makeStyle(style); +function makeLegendStyle(style, theme) { + const sourceStyle = makeStyle(style, theme); const sourceLayers = sourceStyle.layers.filter(layer => layer.type !== 'raster' && layer.type !== 'background'); const legendZoomLevels = [...Array(glodalMaxZoom - globalMinZoom + 1).keys()].map(zoom => globalMinZoom + zoom); @@ -5451,6 +5455,8 @@ function makeLegendStyle(style) { } knownStyles.forEach(style => { - fs.writeFileSync(`${style}.json`, JSON.stringify(makeStyle(style))); - fs.writeFileSync(`legend-${style}.json`, JSON.stringify(makeLegendStyle(style))); + knownThemes.forEach(theme => { + fs.writeFileSync(`${style}-${theme}.json`, JSON.stringify(makeStyle(style, theme))); + fs.writeFileSync(`legend-${style}-${theme}.json`, JSON.stringify(makeLegendStyle(style, theme))); + }); }); diff --git a/proxy/js/ui.js b/proxy/js/ui.js index cbf39adf..d30d98b6 100644 --- a/proxy/js/ui.js +++ b/proxy/js/ui.js @@ -285,6 +285,11 @@ const knownStyles = { track_class: 'Track class', }; +const knownThemes = [ + 'light', + 'dark', +] + function hashToObject(hash) { if (!hash) { return {}; @@ -404,8 +409,16 @@ function resolveTheme(configuredTheme) { : configuredTheme; } +function onThemeChange(theme) { + updateConfiguration('theme', theme); + updateTheme(); + onStyleChange(); +} + function updateTheme() { - document.documentElement.setAttribute('data-bs-theme', resolveTheme(configuration.theme ?? defaultConfiguration.theme)); + const resolvedTheme = resolveTheme(configuration.theme ?? defaultConfiguration.theme) + document.documentElement.setAttribute('data-bs-theme', resolvedTheme); + selectedTheme = resolvedTheme; } function updateBackgroundMapContainer() { @@ -422,6 +435,7 @@ const defaultConfiguration = { let configuration = readConfiguration(localStorage); configuration = migrateConfiguration(localStorage, configuration); +let selectedTheme; updateTheme(); const coordinateFactor = legendZoom => Math.pow(2, 5 - legendZoom); @@ -430,13 +444,20 @@ const legendPointToMapPoint = (zoom, [x, y]) => [x * coordinateFactor(zoom), y * coordinateFactor(zoom)] const mapStyles = Object.fromEntries( - Object.keys(knownStyles) - .map(style => [style, `${location.origin}/style/${style}.json`]) + knownThemes.map(theme => + [theme, Object.fromEntries( + Object.keys(knownStyles) + .map(style => [style, `${location.origin}/style/${style}-${theme}.json`]) + ) + ]) ); const legendStyles = Object.fromEntries( - Object.keys(knownStyles) - .map(style => [style, `${location.origin}/style/legend-${style}.json`]) + knownThemes.map(theme => [theme, Object.fromEntries( + Object.keys(knownStyles) + .map(style => [style, `${location.origin}/style/legend-${style}-${theme}.json`]) + ) + ]) ); const legendMap = new maplibregl.Map({ @@ -466,69 +487,26 @@ const map = new maplibregl.Map({ maxPitch: 0, }); -const onStyleChange = changedStyle => { - selectedStyle = changedStyle; - +const onStyleChange = () => { // Change styles - map.setStyle(mapStyles[changedStyle], { + map.setStyle(mapStyles[selectedTheme][selectedStyle], { validate: false, - transformStyle: (previous, next) => { - let style = next; - - // Apply theme to style - if (resolveTheme(configuration.theme ?? defaultConfiguration.theme) === 'dark') { - style = { - ...style, - layers: style.layers.map(layer => { - if (layer.paint) { - if (layer.paint['text-color'] === 'black') { - layer.paint['text-color'] = 'white' - layer.paint['text-halo-color'] = 'black' - } - } - - return layer; - }) - } - } - - return style; - }, }); - legendMap.setStyle(legendStyles[changedStyle], { + legendMap.setStyle(legendStyles[selectedTheme][selectedStyle], { validate: false, transformStyle: (previous, next) => { - let style = next; - - // Apply theme to style - if (resolveTheme(configuration.theme ?? defaultConfiguration.theme) === 'dark') { - style = { - ...style, - layers: style.layers.map(layer => { - if (layer.paint) { - if (layer.paint['text-color'] === 'black') { - layer.paint['text-color'] = 'white' - layer.paint['text-halo-color'] = 'black' - } - } - - return layer; - }) - } - } - - onStylesheetChange(style); - return style; + onStylesheetChange(next); + return next; }, }); // Update URL - const updatedHash = putStyleInHash(window.location.hash, changedStyle); + const updatedHash = putStyleInHash(window.location.hash, selectedStyle); const location = window.location.href.replace(/(#.+)?$/, updatedHash); window.history.replaceState(window.history.state, null, location); } -onStyleChange(selectedStyle); +onStyleChange(); class StyleControl { constructor(options) { @@ -653,7 +631,10 @@ const legendEntriesCount = Object.fromEntries(Object.keys(knownStyles).map(key = map.addControl(new StyleControl({ initialSelection: selectedStyle, - onStyleChange, + onStyleChange: style => { + selectedStyle = style; + onStyleChange(); + }, })); map.addControl(new maplibregl.NavigationControl({ showCompass: true,