Use Ash palette for weather themes with smooth 5-minute interpolation
This commit is contained in:
1 parent
fa545513a0
commit
33d6635b24
1 file changed
+132
-1
+132
-1
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user