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 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() {
|
function animate() {
|
||||||
var elapsed = (Date.now() - startTime) % CYCLE;
|
var elapsed = (Date.now() - startTime) % CYCLE;
|
||||||
var t = elapsed / CYCLE;
|
var t = elapsed / CYCLE;
|
||||||
var c = getColor(t);
|
var c = getColor(t);
|
||||||
|
c = applyWeatherTheme(c);
|
||||||
effect.setOptions({
|
effect.setOptions({
|
||||||
skyColor: c.sky,
|
skyColor: c.sky,
|
||||||
cloudColor: c.cloud,
|
cloudColor: c.cloud,
|
||||||
@@ -746,7 +875,8 @@
|
|||||||
sunColor: c.sun,
|
sunColor: c.sun,
|
||||||
sunGlareColor: c.sunGlare,
|
sunGlareColor: c.sunGlare,
|
||||||
sunlightColor: c.sunLight,
|
sunlightColor: c.sunLight,
|
||||||
backgroundColor: c.bg
|
backgroundColor: c.bg,
|
||||||
|
speed: currentThemeSpeed
|
||||||
});
|
});
|
||||||
document.body.style.backgroundColor = '#' + ('00000' + c.bg.toString(16)).slice(-6);
|
document.body.style.backgroundColor = '#' + ('00000' + c.bg.toString(16)).slice(-6);
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
@@ -849,6 +979,7 @@
|
|||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
weatherData = data;
|
weatherData = data;
|
||||||
currentWeatherCode = data.current.weather_code;
|
currentWeatherCode = data.current.weather_code;
|
||||||
|
setWeatherTheme(getWeatherThemeName(currentWeatherCode));
|
||||||
updateWeatherDisplay();
|
updateWeatherDisplay();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
|
|||||||
Reference in new issue
Block a user