Fix day cycle
This commit is contained in:
fraxle
2026-06-07 16:28:10 +01:00
parent 80dc28a13e
commit 10452115d7
3 changed files with 15 additions and 8 deletions
+12 -5
View File
@@ -35,6 +35,7 @@ import { POLLEN_TYPES, COL_DESCRIPTIONS, UTCI_ENVIRONMENTS } from './config.js';
import { useAppState } from './hooks/useAppState.js';
import { DayTabs } from './components/DayTabs.js';
import { computeWhyFeelsLike, computeGlanceSummary } from './compute.js';
import { solarElevationDeg } from './physics.js';
import { exportDayXls } from './export.js';
const html = htm.bind(h);
@@ -262,13 +263,19 @@ export function UTCIForecast() {
// Derived from currentRow and the active day - no side effects.
const whyFeelsLike = computeWhyFeelsLike(currentRow ?? null, UTCI_ENVIRONMENTS[utciEnv]);
// During time-lapse, the scope reads an interpolated row at the simulated
// instant instead of the live "now" row. Everything else stays on real now.
// Interpolated row at the precise current instant — used for the scope
// display even outside playback so there's no jump when play is pressed.
const nowRow = interpolateRowAt(hourlyRows, now.getTime());
// During time-lapse, advance from simMs; otherwise fall back to nowRow/currentRow.
const simRow = (playing && simMs != null) ? interpolateRowAt(hourlyRows, simMs) : null;
const scopeRow = simRow || currentRow;
const scopeElev = simRow ? simRow.elev : (liveElev ?? currentRow?.elev ?? 0);
const scopeRow = simRow || nowRow || currentRow;
// Elevation computed continuously from the simulated instant so the sun
// starts exactly where liveElev left off (same solarElevationDeg call).
const scopeElev = (playing && simMs != null && location?.lat != null)
? solarElevationDeg(location.lat, location.lon, new Date(simMs))
: (liveElev ?? currentRow?.elev ?? 0);
const scopeDt = simRow ? simRow.dt : now;
const scopeCat = simRow ? utciCategory(simRow.utciAdj) : currentCat;
const scopeCat = scopeRow ? utciCategory(scopeRow.utciAdj) : currentCat;
// 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;
+2 -2
View File
@@ -616,7 +616,7 @@ export function ScopeReticle({ value, cat, loading, elev = 0, dt = new Date(), g
c = blendHex(c, greyTarget, tintAmt * 0.3); // weather grey
return c;
}
const snowTone = blendHex(skyBotTint, '#ffffff', 0.6); // snow caps (dim at night)
const snowTone = blendHex(skyBotTint, '#ffffff', isDay ? 0.6 : isTwil ? 0.38 : 0.20);
// Readout scrim colour: light by day (dark text), dark by night (light text).
const scrimColor = isDay ? '#f1e8d0' : '#0b0916';
@@ -693,7 +693,7 @@ export function ScopeReticle({ value, cat, loading, elev = 0, dt = new Date(), g
// Alpine: a distant range of irregular, jagged peaks (not pyramids) —
// off-centre summits with sub-shoulders, hazier the further back.
if (spec.obj.mountains) {
const capTone = blendHex(skyBotTint, '#ffffff', 0.72); // snow, cycle-lit
const capTone = blendHex(skyBotTint, '#ffffff', isDay ? 0.72 : isTwil ? 0.46 : 0.24);
const mtn = (x, w, h, seed, d) => {
const r = seededRng(seed);
const tone = objTone('#6a6258', d); // rocky; far = hazier