Use Ash palette for weather themes with smooth 5-minute interpolation

This commit is contained in:
Richard Zink committed 2026-10-07 09:31:53 +02:00
1 parent fa545513a0
commit 33d6635b24
1 file changed
+132 -1
+132 -1
View File
@@ -735,10 +735,139 @@
var startTime = Date.now();
var weatherThemes = {
sunny: {
skyColor: 0x54514f,
cloudColor: 0xb0a89a,
cloudShadowColor: 0x6d6a63,
sunColor: 0xf3ede1,
sunGlareColor: 0xe0914f,
sunlightColor: 0xe6dfd1,
backgroundColor: 0x54514f,
speed: 0.4
},
cloudy: {
skyColor: 0x6d6a63,
cloudColor: 0x999187,
cloudShadowColor: 0x54514f,
sunColor: 0xe6dfd1,
sunGlareColor: 0xb0a89a,
sunlightColor: 0xb0a89a,
backgroundColor: 0x3a383d,
speed: 0.5
},
stormy: {
skyColor: 0x29282c,
cloudColor: 0x3a383d,
cloudShadowColor: 0x1c1b1f,
sunColor: 0x999187,
sunGlareColor: 0x6d6a63,
sunlightColor: 0x6d6a63,
backgroundColor: 0x100f12,
speed: 1.2
},
night: {
skyColor: 0x100f12,
cloudColor: 0x29282c,
cloudShadowColor: 0x1c1b1f,
sunColor: 0xb0a89a,
sunGlareColor: 0x54514f,
sunlightColor: 0x6d6a63,
backgroundColor: 0x100f12,
speed: 0.2
}
};
function getWeatherThemeName(code) {
if (code === 0) return 'sunny';
if (code >= 1 && code <= 3) return 'cloudy';
if (code >= 45 && code <= 48) return 'cloudy';
if ((code >= 51 && code <= 67) || (code >= 80 && code <= 82) || (code >= 71 && code <= 77) || (code >= 85 && code <= 86)) return 'stormy';
if (code >= 95) return 'stormy';
return 'cloudy';
}
function mixColor(color1, color2, factor) {
if (color1 === undefined || color2 === undefined) return color1 || color2;
var r1 = (color1 >> 16) & 255;
var g1 = (color1 >> 8) & 255;
var b1 = color1 & 255;
var r2 = (color2 >> 16) & 255;
var g2 = (color2 >> 8) & 255;
var b2 = color2 & 255;
var r = Math.round(r1 + (r2 - r1) * factor);
var g = Math.round(g1 + (g2 - g1) * factor);
var b = Math.round(b1 + (b2 - b1) * factor);
return (r << 16) | (g << 8) | b;
}
var prevThemeColors = null;
var targetThemeColors = null;
var transitionStartTime = 0;
var TRANSITION_DURATION = 5 * 60 * 1000;
var currentWeatherThemeName = null;
var currentThemeSpeed = 0.4;
function setWeatherTheme(themeName) {
if (currentWeatherThemeName !== themeName) {
prevThemeColors = getEffectiveThemeColors();
targetThemeColors = weatherThemes[themeName] || weatherThemes.cloudy;
transitionStartTime = Date.now();
currentWeatherThemeName = themeName;
}
}
function getEffectiveThemeColors() {
if (!targetThemeColors) return null;
var elapsed = Date.now() - transitionStartTime;
var smoothT;
if (!prevThemeColors || elapsed >= TRANSITION_DURATION) {
smoothT = 1;
} else {
var t = elapsed / TRANSITION_DURATION;
smoothT = t * t * (3 - 2 * t);
}
var result = {};
var keys = ['skyColor', 'cloudColor', 'cloudShadowColor', 'sunColor', 'sunGlareColor', 'sunlightColor', 'backgroundColor'];
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
if (prevThemeColors && smoothT < 1) {
result[k] = mixColor(prevThemeColors[k], targetThemeColors[k], smoothT);
} else {
result[k] = targetThemeColors[k];
}
}
if (smoothT >= 1 && prevThemeColors !== targetThemeColors) {
prevThemeColors = targetThemeColors;
currentThemeSpeed = targetThemeColors.speed;
}
return result;
}
function applyWeatherTheme(c) {
var themeColors = getEffectiveThemeColors();
if (!themeColors) return c;
var mix = 0.6;
return {
sky: mixColor(c.sky, themeColors.skyColor, mix),
cloud: mixColor(c.cloud, themeColors.cloudColor, mix),
cloudShadow: mixColor(c.cloudShadow, themeColors.cloudShadowColor, mix),
sun: mixColor(c.sun, themeColors.sunColor, mix * 0.5),
sunGlare: mixColor(c.sunGlare, themeColors.sunGlareColor, mix * 0.5),
sunLight: mixColor(c.sunLight, themeColors.sunlightColor, mix * 0.5),
bg: mixColor(c.bg, themeColors.backgroundColor, mix),
sunVis: c.sunVis
};
}
function animate() {
var elapsed = (Date.now() - startTime) % CYCLE;
var t = elapsed / CYCLE;
var c = getColor(t);
c = applyWeatherTheme(c);
effect.setOptions({
skyColor: c.sky,
cloudColor: c.cloud,
@@ -746,7 +875,8 @@
sunColor: c.sun,
sunGlareColor: c.sunGlare,
sunlightColor: c.sunLight,
backgroundColor: c.bg
backgroundColor: c.bg,
speed: currentThemeSpeed
});
document.body.style.backgroundColor = '#' + ('00000' + c.bg.toString(16)).slice(-6);
requestAnimationFrame(animate);
@@ -849,6 +979,7 @@
.then(function(data) {
weatherData = data;
currentWeatherCode = data.current.weather_code;
setWeatherTheme(getWeatherThemeName(currentWeatherCode));
updateWeatherDisplay();
})
.catch(function(err) {