Reload palette and themes when theme changes

This commit is contained in:
Richard Zink committed 2026-10-07 12:27:21 +02:00
1 parent f0f0fa18f6
commit 900831477f
1 file changed
+117 -33
+117 -33
View File
@@ -533,11 +533,92 @@ var effect = (VANTA.CLOUDS2 || VANTA.CLOUDS)({
return parseInt(hex.replace('#', ''), 16); return parseInt(hex.replace('#', ''), 16);
} }
// Refreshable color cache - re-reads from CSS variables when theme changes
function getColors() {
var root = getComputedStyle(document.documentElement);
var keys = [
'void', 'panel', 'raised', 'border', 'mid', 'ash',
'icon', 'stone', 'bone', 'chalk',
'ember', 'gold', 'blood', 'rust', 'rot', 'moss', 'steel', 'steelLight', 'violet'
];
var map = {
void: 'black',
panel: 'dark',
raised: 'gray-darker',
border: 'gray-dark',
mid: 'gray',
ash: 'gray-light',
ember: 'orange',
gold: 'yellow',
blood: 'red',
rust: 'brown',
rot: 'pink',
moss: 'green',
steel: 'blue',
steelLight: 'blue-light',
violet: 'purple'
};
var result = {};
for (var i = 0; i < keys.length; i++) {
var ashKey = keys[i];
var cssKey = map[ashKey] || ashKey;
result[ashKey] = root.getPropertyValue('--' + cssKey).trim();
}
return result;
}
var ASH = getColors(); var ASH = getColors();
function rebuildFromColors() {
ASH = getColors();
// Rebuild palette
window.sunPalettes = [
{ alt: -Math.PI / 2, sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 },
{ alt: -0.1, sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 },
{ alt: 0.0, sky: hexToInt(ASH.rust), cloud: hexToInt(ASH.border), light: hexToInt(ASH.gold), bg: hexToInt(ASH.rust), cloudShadow: hexToInt(ASH.raised), sun: hexToInt(ASH.ember), sunGlare: hexToInt(ASH.gold), sunLight: hexToInt(ASH.ember), sunVis: 0.8 },
{ alt: 0.15, sky: hexToInt(ASH.blood), cloud: hexToInt(ASH.border), light: hexToInt(ASH.ember), bg: hexToInt(ASH.blood), cloudShadow: hexToInt(ASH.raised), sun: hexToInt(ASH.ember), sunGlare: hexToInt(ASH.ember), sunLight: hexToInt(ASH.ember), sunVis: 0.7 },
{ alt: 0.4, sky: hexToInt(ASH.steel), cloud: hexToInt(ASH.border), light: hexToInt(ASH.bone), bg: hexToInt(ASH.steel), cloudShadow: hexToInt(ASH.steel), sun: hexToInt(ASH.chalk), sunGlare: hexToInt(ASH.bone), sunLight: hexToInt(ASH.chalk), sunVis: 1 },
{ alt: Math.PI / 2, sky: hexToInt(ASH.steelLight), cloud: hexToInt(ASH.border), light: hexToInt(ASH.chalk), bg: hexToInt(ASH.steelLight), cloudShadow: hexToInt(ASH.steelLight), sun: hexToInt(ASH.chalk), sunGlare: hexToInt(ASH.bone), sunLight: hexToInt(ASH.chalk), sunVis: 1 }
];
window.nightPaletteNew = { sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone) };
window.nightPaletteFull = { sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.border), light: hexToInt(ASH.icon), bg: hexToInt(ASH.panel), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.icon), sunGlare: hexToInt(ASH.mid), sunLight: hexToInt(ASH.icon) };
window.weatherThemes = {
sunny: {
skyColor: hexToInt(ASH.steelLight),
cloudColor: hexToInt(ASH.stone),
lightColor: hexToInt(ASH.chalk),
backgroundColor: hexToInt(ASH.mid),
speed: 1.0
},
cloudy: {
skyColor: hexToInt(ASH.steel),
cloudColor: hexToInt(ASH.mid),
lightColor: hexToInt(ASH.bone),
backgroundColor: hexToInt(ASH.border),
speed: 1.2
},
stormy: {
skyColor: hexToInt(ASH.steel),
cloudColor: hexToInt(ASH.panel),
lightColor: hexToInt(ASH.stone),
backgroundColor: hexToInt(ASH.void),
speed: 2.5
},
night: {
skyColor: hexToInt(ASH.void),
cloudColor: hexToInt(ASH.raised),
lightColor: hexToInt(ASH.icon),
backgroundColor: hexToInt(ASH.void),
speed: 0.4
}
};
}
// Sun position palette (altitude-based) - all colors from Ash palette // Sun position palette (altitude-based) - all colors from Ash palette
// altitude in radians: -pi/2 (below) to pi/2 (zenith) // altitude in radians: -pi/2 (below) to pi/2 (zenith)
var sunPalettes = [ // Sun position palette (altitude-based) - all colors from current theme
// altitude in radians: -pi/2 (below) to pi/2 (zenith)
window.sunPalettes = [
{ alt: -Math.PI / 2, sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 }, { alt: -Math.PI / 2, sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 },
{ alt: -0.1, sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 }, { alt: -0.1, sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone), sunVis: 0 },
{ alt: 0.0, sky: hexToInt(ASH.rust), cloud: hexToInt(ASH.border), light: hexToInt(ASH.gold), bg: hexToInt(ASH.rust), cloudShadow: hexToInt(ASH.raised), sun: hexToInt(ASH.ember), sunGlare: hexToInt(ASH.gold), sunLight: hexToInt(ASH.ember), sunVis: 0.8 }, { alt: 0.0, sky: hexToInt(ASH.rust), cloud: hexToInt(ASH.border), light: hexToInt(ASH.gold), bg: hexToInt(ASH.rust), cloudShadow: hexToInt(ASH.raised), sun: hexToInt(ASH.ember), sunGlare: hexToInt(ASH.gold), sunLight: hexToInt(ASH.ember), sunVis: 0.8 },
@@ -547,34 +628,34 @@ var effect = (VANTA.CLOUDS2 || VANTA.CLOUDS)({
]; ];
// Night palette based on moon phase (0 = new, 0.5 = full, 1 = new) - Ash colors // Night palette based on moon phase (0 = new, 0.5 = full, 1 = new) - Ash colors
var nightPaletteNew = { sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone) }; window.nightPaletteNew = { sky: hexToInt(ASH.void), cloud: hexToInt(ASH.void), light: hexToInt(ASH.stone), bg: hexToInt(ASH.void), cloudShadow: hexToInt(ASH.void), sun: hexToInt(ASH.stone), sunGlare: hexToInt(ASH.ash), sunLight: hexToInt(ASH.stone) };
var nightPaletteFull = { sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.border), light: hexToInt(ASH.icon), bg: hexToInt(ASH.panel), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.icon), sunGlare: hexToInt(ASH.mid), sunLight: hexToInt(ASH.icon) }; window.nightPaletteFull = { sky: hexToInt(ASH.panel), cloud: hexToInt(ASH.border), light: hexToInt(ASH.icon), bg: hexToInt(ASH.panel), cloudShadow: hexToInt(ASH.panel), sun: hexToInt(ASH.icon), sunGlare: hexToInt(ASH.mid), sunLight: hexToInt(ASH.icon) };
var MIN_NIGHT_BRIGHTNESS = 0.25; // minimum night brightness (even at new moon) var MIN_NIGHT_BRIGHTNESS = 0.25; // minimum night brightness (even at new moon)
function getDayColor(sunAlt) { function getDayColor(sunAlt) {
// Find palette segment based on sun altitude // Find palette segment based on sun altitude
var palette; var palette;
if (sunAlt <= sunPalettes[0].alt) { if (sunAlt <= window.sunPalettes[0].alt) {
palette = sunPalettes[0]; palette = window.sunPalettes[0];
} else if (sunAlt >= sunPalettes[sunPalettes.length - 1].alt) { } else if (sunAlt >= window.sunPalettes[window.sunPalettes.length - 1].alt) {
palette = sunPalettes[sunPalettes.length - 1]; palette = window.sunPalettes[window.sunPalettes.length - 1];
} else { } else {
for (var i = 0; i < sunPalettes.length - 1; i++) { for (var i = 0; i < window.sunPalettes.length - 1; i++) {
if (sunAlt >= sunPalettes[i].alt && sunAlt <= sunPalettes[i + 1].alt) { if (sunAlt >= window.sunPalettes[i].alt && sunAlt <= window.sunPalettes[i + 1].alt) {
var span = sunPalettes[i + 1].alt - sunPalettes[i].alt; var span = window.sunPalettes[i + 1].alt - window.sunPalettes[i].alt;
var localT = span === 0 ? 0 : (sunAlt - sunPalettes[i].alt) / span; var localT = span === 0 ? 0 : (sunAlt - window.sunPalettes[i].alt) / span;
var s = smooth(localT); var s = smooth(localT);
palette = { palette = {
sky: lerpColor(sunPalettes[i].sky, sunPalettes[i + 1].sky, s), sky: lerpColor(window.sunPalettes[i].sky, window.sunPalettes[i + 1].sky, s),
cloud: lerpColor(sunPalettes[i].cloud, sunPalettes[i + 1].cloud, s), cloud: lerpColor(window.sunPalettes[i].cloud, window.sunPalettes[i + 1].cloud, s),
light: lerpColor(sunPalettes[i].light, sunPalettes[i + 1].light, s), light: lerpColor(window.sunPalettes[i].light, window.sunPalettes[i + 1].light, s),
bg: lerpColor(sunPalettes[i].bg, sunPalettes[i + 1].bg, s), bg: lerpColor(window.sunPalettes[i].bg, window.sunPalettes[i + 1].bg, s),
cloudShadow: lerpColor(sunPalettes[i].cloudShadow, sunPalettes[i + 1].cloudShadow, s), cloudShadow: lerpColor(window.sunPalettes[i].cloudShadow, window.sunPalettes[i + 1].cloudShadow, s),
sun: lerpColor(sunPalettes[i].sun, sunPalettes[i + 1].sun, s), sun: lerpColor(window.sunPalettes[i].sun, window.sunPalettes[i + 1].sun, s),
sunGlare: lerpColor(sunPalettes[i].sunGlare, sunPalettes[i + 1].sunGlare, s), sunGlare: lerpColor(window.sunPalettes[i].sunGlare, window.sunPalettes[i + 1].sunGlare, s),
sunLight: lerpColor(sunPalettes[i].sunLight, sunPalettes[i + 1].sunLight, s), sunLight: lerpColor(window.sunPalettes[i].sunLight, window.sunPalettes[i + 1].sunLight, s),
sunVis: sunPalettes[i].sunVis + (sunPalettes[i + 1].sunVis - sunPalettes[i].sunVis) * s sunVis: window.sunPalettes[i].sunVis + (window.sunPalettes[i + 1].sunVis - window.sunPalettes[i].sunVis) * s
}; };
break; break;
} }
@@ -590,14 +671,14 @@ var effect = (VANTA.CLOUDS2 || VANTA.CLOUDS)({
// Interpolate between new and full moon palette based on fraction // Interpolate between new and full moon palette based on fraction
var s = moonIllum.fraction; var s = moonIllum.fraction;
var c = { var c = {
sky: lerpColor(nightPaletteNew.sky, nightPaletteFull.sky, s), sky: lerpColor(window.nightPaletteNew.sky, window.nightPaletteFull.sky, s),
cloud: lerpColor(nightPaletteNew.cloud, nightPaletteFull.cloud, s), cloud: lerpColor(window.nightPaletteNew.cloud, window.nightPaletteFull.cloud, s),
light: lerpColor(nightPaletteNew.light, nightPaletteFull.light, s), light: lerpColor(window.nightPaletteNew.light, window.nightPaletteFull.light, s),
bg: lerpColor(nightPaletteNew.bg, nightPaletteFull.bg, s), bg: lerpColor(window.nightPaletteNew.bg, window.nightPaletteFull.bg, s),
cloudShadow: lerpColor(nightPaletteNew.cloudShadow, nightPaletteFull.cloudShadow, s), cloudShadow: lerpColor(window.nightPaletteNew.cloudShadow, window.nightPaletteFull.cloudShadow, s),
sun: lerpColor(nightPaletteNew.sun, nightPaletteFull.sun, s), sun: lerpColor(window.nightPaletteNew.sun, window.nightPaletteFull.sun, s),
sunGlare: lerpColor(nightPaletteNew.sunGlare, nightPaletteFull.sunGlare, s), sunGlare: lerpColor(window.nightPaletteNew.sunGlare, window.nightPaletteFull.sunGlare, s),
sunLight: lerpColor(nightPaletteNew.sunLight, nightPaletteFull.sunLight, s) sunLight: lerpColor(window.nightPaletteNew.sunLight, window.nightPaletteFull.sunLight, s)
}; };
// Apply brightness factor (relative to mid) // Apply brightness factor (relative to mid)
return c; return c;
@@ -1054,7 +1135,7 @@ if (moonTimes.set) {
var startTime = Date.now(); var startTime = Date.now();
var weatherThemes = { var window.weatherThemes = {
sunny: { sunny: {
skyColor: hexToInt(ASH.steelLight), skyColor: hexToInt(ASH.steelLight),
cloudColor: hexToInt(ASH.stone), cloudColor: hexToInt(ASH.stone),
@@ -1118,7 +1199,7 @@ var weatherThemes = {
function setWeatherTheme(themeName) { function setWeatherTheme(themeName) {
if (currentWeatherThemeName !== themeName) { if (currentWeatherThemeName !== themeName) {
prevThemeColors = getEffectiveThemeColors(); prevThemeColors = getEffectiveThemeColors();
targetThemeColors = weatherThemes[themeName] || weatherThemes.cloudy; targetThemeColors = window.weatherThemes[themeName] || window.weatherThemes.cloudy;
transitionStartTime = Date.now(); transitionStartTime = Date.now();
currentWeatherThemeName = themeName; currentWeatherThemeName = themeName;
} }
@@ -1192,7 +1273,10 @@ var weatherThemes = {
var themeMap = { ash: 'ash.css', gruvbox: 'gruvbox.css' }; var themeMap = { ash: 'ash.css', gruvbox: 'gruvbox.css' };
var css = document.getElementById('theme-css'); var css = document.getElementById('theme-css');
if (css && themeMap[theme]) css.href = themeMap[theme]; if (css && themeMap[theme]) css.href = themeMap[theme];
document.getElementById('dbg-palette-name').textContent = theme.charAt(0).toUpperCase() + theme.slice(1); setTimeout(function() {
rebuildFromColors();
document.getElementById('dbg-palette-name').textContent = theme.charAt(0).toUpperCase() + theme.slice(1);
}, 50);
window.CONFIG.theme = theme; window.CONFIG.theme = theme;
} }
@@ -1211,7 +1295,7 @@ var weatherThemes = {
(hh < 10 ? '0' : '') + hh + ':' + (mm < 10 ? '0' : '') + mm + ':' + (ss < 10 ? '0' : '') + ss; (hh < 10 ? '0' : '') + hh + ':' + (mm < 10 ? '0' : '') + mm + ':' + (ss < 10 ? '0' : '') + ss;
document.getElementById('dbg-day').textContent = realDayProgress != null ? (realDayProgress * 100).toFixed(1) + '%' : (t * 100).toFixed(1) + '%'; document.getElementById('dbg-day').textContent = realDayProgress != null ? (realDayProgress * 100).toFixed(1) + '%' : (t * 100).toFixed(1) + '%';
document.getElementById('dbg-weather').textContent = document.getElementById('dbg-weather').textContent =
currentWeatherCode + ' (' + (weatherThemes[themeName] ? themeName : '?') + ')'; currentWeatherCode + ' (' + (window.weatherThemes[themeName] ? themeName : '?') + ')';
document.getElementById('dbg-theme').textContent = themeName || '-'; document.getElementById('dbg-theme').textContent = themeName || '-';
document.getElementById('dbg-speed').textContent = currentThemeSpeed.toFixed(2); document.getElementById('dbg-speed').textContent = currentThemeSpeed.toFixed(2);
@@ -1261,7 +1345,7 @@ var weatherThemes = {
tableHtml += '</div>'; tableHtml += '</div>';
for (var n = 0; n < themeNames.length; n++) { for (var n = 0; n < themeNames.length; n++) {
var tn = themeNames[n]; var tn = themeNames[n];
var th = weatherThemes[tn]; var th = window.weatherThemes[tn];
tableHtml += '<div class="theme-table-row">'; tableHtml += '<div class="theme-table-row">';
tableHtml += '<span class="theme-table-name">' + tn + '</span>'; tableHtml += '<span class="theme-table-name">' + tn + '</span>';
for (var f = 0; f < themeFields.length; f++) { for (var f = 0; f < themeFields.length; f++) {