5.0.8
Day tab colour update Cleanup event banner and add close
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
|
||||
import { h, Fragment } from '../../vendor/preact.js';
|
||||
import htm from '../../vendor/htm.js';
|
||||
import { confidenceBand, utciCategory, petCategory, hexToRgb, mixRgb, rainTint, cloudTint, snowTint, VEHICLE_TYPES, BUILDING_TYPES, FUR_COLORS } from '../utils.js';
|
||||
import { confidenceBand, utciCategory, petCategory, UTCI_BANDS, PET_BANDS, bandRampRgb, hexToRgb, mixRgb, rainTint, cloudTint, snowTint, VEHICLE_TYPES, BUILDING_TYPES, FUR_COLORS } from '../utils.js';
|
||||
import { FREE_DAYS, UTCI_ENVIRONMENTS, deriveProfileMain, FILTER_PROFILES, variantIcons } from '../config.js';
|
||||
import { CloudIcon, PrecipIcon, HouseIcon, CarIcon, FogIcon, IceIcon } from '../components.js';
|
||||
import { SubscribeModal } from './SubscribeModal.js';
|
||||
@@ -292,6 +292,14 @@ export function DayTabs({
|
||||
// event banner can colour itself from exactly the same source.
|
||||
const catFn = isPetsProfile ? petCategory : utciCategory;
|
||||
const tBand = dayHi !== null ? catFn(dayHi) : { bg: '#f8e554' };
|
||||
// Band colour, but ramped: bandRampRgb() interpolates between the
|
||||
// this band's colour and the next one's, so 30° isn't the same
|
||||
// swatch as 27° while 32° still lands on the Extreme orange
|
||||
// (see BAND COLOUR RAMP in utils.js). Danger stays flat — it's an
|
||||
// alarm colour, not a point on the gradient.
|
||||
const tBandRgb = tBand.solid
|
||||
? hexToRgb(tBand.bg)
|
||||
: bandRampRgb(dayHi, isPetsProfile ? PET_BANDS : UTCI_BANDS);
|
||||
|
||||
const ccVals = repRows.map(r => r.cc).filter(v => isFinite(v));
|
||||
const avgCloud = ccVals.length ? ccVals.reduce((s, v) => s + v, 0) / ccVals.length : 0;
|
||||
@@ -314,7 +322,7 @@ export function DayTabs({
|
||||
|
||||
let rgb;
|
||||
if (tempOnly) {
|
||||
rgb = hexToRgb(tBand.bg);
|
||||
rgb = tBandRgb;
|
||||
} else if (isHot) {
|
||||
// Keep the heat hue; cloud only mutes it a touch (orange/red never
|
||||
// greens) and rain does not override heat.
|
||||
@@ -322,7 +330,7 @@ export function DayTabs({
|
||||
? (dayHi >= 49 ? 0.15 : dayHi >= 43 ? 0.30 : 0.45)
|
||||
: (dayHi >= 39 ? 0.15 : dayHi >= 34 ? 0.30 : 0.45);
|
||||
const t = Math.max(0, Math.min(1, (avgCloud - 30) / 70)) * heatFactor;
|
||||
rgb = mixRgb(hexToRgb(tBand.bg), [170, 162, 152], t);
|
||||
rgb = mixRgb(tBandRgb, [170, 162, 152], t);
|
||||
} else if (daySnow >= 0.1) {
|
||||
// Snow: pale → icy blue with depth.
|
||||
rgb = snowTint(daySnow);
|
||||
@@ -334,7 +342,7 @@ export function DayTabs({
|
||||
rgb = cloudTint(avgCloud);
|
||||
} else if (dayHi !== null && dayHi < (isPetsProfile ? 2 : 10)) {
|
||||
// Clear & cold: keep the cold temperature blue.
|
||||
rgb = hexToRgb(tBand.bg);
|
||||
rgb = tBandRgb;
|
||||
} else {
|
||||
// Clear & mild/warm: a plain sunny yellow.
|
||||
rgb = hexToRgb('#f8e554');
|
||||
@@ -350,16 +358,29 @@ export function DayTabs({
|
||||
}
|
||||
const [wR, wG, wB] = rgb;
|
||||
|
||||
const wBgNeutral = isDanger
|
||||
? weatherGradientNeutral(wR, wG, wB, 0.15, 0.72)
|
||||
: isExtreme
|
||||
? weatherGradientNeutral(wR, wG, wB, 0.20, 0.66)
|
||||
: weatherGradientNeutral(wR, wG, wB);
|
||||
const wBgActive = isDanger
|
||||
? weatherGradientActive(wR, wG, wB, 0.12, 0.72)
|
||||
: isExtreme
|
||||
? weatherGradientActive(wR, wG, wB, 0.16, 0.66)
|
||||
: weatherGradientActive(wR, wG, wB);
|
||||
// How pastel the tab is drawn also carries heat: the tint is blended
|
||||
// toward white, and the hotter the day the less white goes in. This
|
||||
// used to step at the band edges (0.50 for everything up to Caution,
|
||||
// then 0.20 at Extreme), which made 30° look like a washed-out yellow
|
||||
// while 32° snapped to a solid orange. Ramp the blend continuously
|
||||
// instead — the endpoints still land on the old Extreme (heatT = 1)
|
||||
// and Danger (both = 1) values, so only the in-between days change.
|
||||
const heatFloor = isPetsProfile ? 35 : 27; // start of the hot half
|
||||
const heatMid = isPetsProfile ? 40 : 32; // Extreme threshold
|
||||
const heatTop = isPetsProfile ? 52 : 41; // Danger threshold
|
||||
const clamp01 = (v) => Math.max(0, Math.min(1, v));
|
||||
const heatT = dayHi === null ? 0 : clamp01((dayHi - heatFloor) / (heatMid - heatFloor));
|
||||
const overT = dayHi === null ? 0 : clamp01((dayHi - heatMid) / (heatTop - heatMid));
|
||||
const wBgNeutral = weatherGradientNeutral(
|
||||
wR, wG, wB,
|
||||
0.50 - 0.30 * heatT - 0.05 * overT, // edge: 0.50 → 0.20 → 0.15
|
||||
0.69 - 0.03 * heatT + 0.06 * overT, // centre: 0.69 → 0.66 → 0.72
|
||||
);
|
||||
const wBgActive = weatherGradientActive(
|
||||
wR, wG, wB,
|
||||
0.42 - 0.26 * heatT - 0.04 * overT, // edge: 0.42 → 0.16 → 0.12
|
||||
0.64 + 0.02 * heatT + 0.06 * overT, // centre: 0.64 → 0.66 → 0.72
|
||||
);
|
||||
const wText = '#2a1d10';
|
||||
// Active-tab outline: the day's weather colour, 20% darker.
|
||||
const wOutline = `rgb(${Math.round(wR * 0.8)},${Math.round(wG * 0.8)},${Math.round(wB * 0.8)})`;
|
||||
|
||||
Reference in New Issue
Block a user