Skip to content

Commit

Permalink
generate theme-specific style JSON files
Browse files Browse the repository at this point in the history
  • Loading branch information
hiddewie committed Dec 7, 2024
1 parent e5bbd49 commit 519bc8e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 64 deletions.
6 changes: 3 additions & 3 deletions proxy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ <h5 class="modal-title">Map configuration</h5>
<label class="form-label">Theme</label>
<div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="theme" id="themeSystem" value="system" checked onchange="updateConfiguration('theme', 'system'); updateTheme();">
<input class="form-check-input" type="radio" name="theme" id="themeSystem" value="system" checked onchange="onThemeChange('system');">
<label class="form-check-label" for="themeSystem">System</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="theme" id="themeLight" value="light" onchange="updateConfiguration('theme', 'light'); updateTheme();">
<input class="form-check-input" type="radio" name="theme" id="themeLight" value="light" onchange="onThemeChange('light');">
<label class="form-check-label" for="themeLight">Light</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="theme" id="themeDark" value="dark" onchange="updateConfiguration('theme', 'dark'); updateTheme();">
<input class="form-check-input" type="radio" name="theme" id="themeDark" value="dark" onchange="onThemeChange('dark');">
<label class="form-check-label" for="themeDark">Dark</label>
</div>
</div>
Expand Down
16 changes: 11 additions & 5 deletions proxy/js/styles.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const knownStyles = [
'loading_gauge',
'track_class',
];
const knownThemes = [
'light',
'dark',
];

const globalMinZoom = 1;
const glodalMaxZoom = 20;
Expand Down Expand Up @@ -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}`,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)));
});
});
93 changes: 37 additions & 56 deletions proxy/js/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ const knownStyles = {
track_class: 'Track class',
};

const knownThemes = [
'light',
'dark',
]

function hashToObject(hash) {
if (!hash) {
return {};
Expand Down Expand Up @@ -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() {
Expand All @@ -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);
Expand All @@ -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({
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 519bc8e

Please sign in to comment.