From 33d6635b24a4b9c312bfee06d7cdc501ef9c6088 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Wed, 7 Oct 2026 09:31:53 +0200 Subject: [PATCH] Use Ash palette for weather themes with smooth 5-minute interpolation --- index.html | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index f4c8a5b..5c0a2ca 100644 --- a/index.html +++ b/index.html @@ -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) {