Why it feels now updates on play
This commit is contained in:
fraxle
2026-06-27 07:47:04 +01:00
parent efcf2d621c
commit 05ab4cf76b
2 changed files with 34 additions and 9 deletions
+18 -5
View File
@@ -69,6 +69,12 @@ function interpolateRowAt(rows, t) {
elev: L(lo.elev, hi.elev),
glob: L(lo.glob, hi.glob),
utciAdj: L(lo.utciAdj, hi.utciAdj),
// Felt-temp inputs — interpolated so the "Why It Feels" panel breakdown
// stays smooth and consistent with the (interpolated) utciAdj category.
Ta: L(lo.Ta, hi.Ta),
Tmrt: L(lo.Tmrt, hi.Tmrt),
va: L(lo.va, hi.va),
eh: L(lo.eh, hi.eh),
cc: L(lo.cc, hi.cc),
ccLow: L(lo.ccLow, hi.ccLow),
ccMid: L(lo.ccMid, hi.ccMid),
@@ -413,8 +419,8 @@ export function UTCIForecast() {
const airTempRgbVeryStrong = (t) => airTempRgb(t, 0.25);
// ─── 3b. PANEL COMPUTATIONS ──────────────────────────────────────────
// Derived from currentRow and the active day - no side effects.
const whyFeelsLike = computeWhyFeelsLike(currentRow ?? null, UTCI_ENVIRONMENTS[utciEnv]);
// whyFeelsLike is derived below, after the playback rows are resolved, so
// the panel can track the simulated instant during play/scrub (see panelRow).
// Interpolated row at the precise current instant — used for the scope
// display even outside playback so there's no jump when play is pressed.
@@ -432,6 +438,13 @@ export function UTCIForecast() {
: (liveElev ?? currentRow?.elev ?? 0);
const scopeDt = simRow ? simRow.dt : now;
const scopeCat = scopeRow ? utciCategory(scopeRow.utciAdj) : currentCat;
// "Why It Feels" panel always mirrors the scope dial: the simulated instant
// during play/scrub, and the interpolated "now" row (scopeRow → nowRow) when
// stopped. Sharing scopeRow/scopeCat guarantees the panel's thermal label can
// never disagree with the dial's reticle.
const panelRow = scopeRow;
const panelCat = scopeCat;
const whyFeelsLike = computeWhyFeelsLike(panelRow ?? null, UTCI_ENVIRONMENTS[utciEnv]);
// Synthesize a storm overlay (lightning) when the simulated hour is wet;
// outside playback keep the real active event.
const scopeEvent = simRow ? ((simRow.precip ?? 0) >= 4 ? { id: 'storm' } : null) : lensEvent;
@@ -751,7 +764,7 @@ export function UTCIForecast() {
</div>
<div class="header-right">
${forecast && currentRow && whyFeelsLike && html`
${forecast && panelRow && whyFeelsLike && html`
<div class="insight-panel insight-panel--why">
<div class="insight-env-footer" data-env=${utciEnv}>
<span class="insight-env-footer-label">Solar model</span>
@@ -769,11 +782,11 @@ export function UTCIForecast() {
</div>
<div class="insight-panel-title">
Why It Feels
${currentCat && html`<span class="insight-thermal-cat" style=${{ background: currentCat.bg, color: currentCat.fg }}>${currentCat.label}</span>`}
${panelCat && html`<span class="insight-thermal-cat" style=${{ background: panelCat.bg, color: panelCat.fg }}>${panelCat.label}</span>`}
</div>
${(() => {
const _wflItems = [
{ label: 'Air temperature', icon: '🌡', value: currentRow.Ta, isBase: true },
{ label: 'Air temperature', icon: '🌡', value: panelRow.Ta, isBase: true },
{ label: 'Sun and sky', icon: '☀', value: whyFeelsLike.sunAndSky },
{ label: 'Wind', icon: '🌬', value: whyFeelsLike.wind },
{ label: 'Humidity', icon: '💧', value: whyFeelsLike.humidity },
+16 -4
View File
@@ -484,15 +484,27 @@ export function DayTabs({
title: 'Office is part of SunScope Extra',
detail: 'Extra adds the Office profile with solar gain, managed indoor temperature, humidity, air quality, and rain probability — useful for commute planning and building comfort.',
},
'variant:driver': {
title: 'Driver / Trucker is part of SunScope Extra',
detail: 'Extra adds the Driver / Trucker profile with vehicle interior temperature, UV, wind speed and direction, rain probability, and visibility — the conditions that matter for long hours on the road.',
},
'export': {
title: 'Export day data is part of SunScope Extra',
detail: 'Extra lets you download a full hourly spreadsheet for any day — all 41 columns including felt temperature, UV, soil, wind, and air quality, styled and ready to use in Excel or LibreOffice.',
},
};
const promptCopy = extraPromptCopy[proPromptSource] || {
title: `${dayName}'s forecast is part of SunScope Extra`,
detail: 'Extra unlocks the full 14-day forecast, customisable columns, specialist profiles, and an ad-free view.',
};
// Day-tab locks get the day-specific heading; any other locked feature
// without its own entry above falls back to a feature-agnostic message.
const fallbackCopy = proPromptSource === 'day'
? {
title: `${dayName}'s forecast is part of SunScope Extra`,
detail: 'Extra unlocks the full 14-day forecast, customisable columns, specialist profiles, and an ad-free view.',
}
: {
title: 'This is part of SunScope Extra',
detail: 'Extra unlocks the full 14-day forecast, customisable columns, specialist profiles, and an ad-free view.',
};
const promptCopy = extraPromptCopy[proPromptSource] || fallbackCopy;
return html`
<${SubscribeModal}
title=${promptCopy.title}