mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
At dawn, dusk and night the environment shows the moon in the top-left corner of the scene, behind the plan: computed in the card from the home coordinates and the browser clock (short Meeus series + topocentric parallax, within 1.4° / 1.8 pp of JPL Horizons), one designer image under a continuous phase mask with the lit side always on the left (owner 2026-09-29), a feathered terminator, 3°/3 % thresholds and the 2 s fade of the window rays. Everything but a small gate lives in the lazy moon-runtime chunk, with its own 30 s ticker. General settings: "Sun" becomes "Sun and Moon" with one switch, on for new installations (DEFAULT_CONFIG), off for existing ones. The initial View graph sat 728 B under its budget: the gate is paid for by moving fifteen dialog-only strings of General settings into the lazy settings dictionary (#459) and by one build fingerprint literal instead of three, so the graph ends 4 B above dev. Golden: two new moon scenes, and the two General settings help frames show «Sun and Moon»; the WSL artifact test fixture now models scenes whose first capture awaits acceptance. Issue: #661 User-Visible: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
50 lines
2.2 KiB
TypeScript
50 lines
2.2 KiB
TypeScript
/** Shared four-phase environment templates for full and static cards (#146). */
|
|
import { html, nothing, type TemplateResult } from 'lit';
|
|
import {
|
|
DAY_CYCLE_PALETTES, type DayCyclePhase, type DayCycleState,
|
|
} from './sun';
|
|
|
|
const PHASES: readonly DayCyclePhase[] = ['dawn', 'day', 'dusk', 'night'];
|
|
|
|
/** CSS variables owned by the stage rather than copied into its plan tree. */
|
|
export function dayCycleStageVars(state: DayCycleState | null): string {
|
|
if (!state) return '';
|
|
const palette = DAY_CYCLE_PALETTES[state.phase];
|
|
return [
|
|
`--hp-day-cycle-outline-near:${palette.outlineNear}`,
|
|
`--hp-day-cycle-outline-mid:${palette.outlineMid}`,
|
|
`--hp-day-cycle-outline-far:${palette.outlineFar}`,
|
|
].join(';');
|
|
}
|
|
|
|
/**
|
|
* Four constant layers make gradient changes genuinely cross-fade in CSS. The
|
|
* moon (#661) comes last: above the gradients and the sun glow, still inside
|
|
* the environment and therefore below the plan paper and everything else.
|
|
*/
|
|
export function renderDayCycleEnvironment(
|
|
state: DayCycleState | null,
|
|
viewWeight = 1,
|
|
moon: TemplateResult | typeof nothing = nothing,
|
|
): TemplateResult | typeof nothing {
|
|
if (!state) return nothing;
|
|
const position = [
|
|
`--hp-day-cycle-sun-x:${state.sunX.toFixed(2)}%`,
|
|
`--hp-day-cycle-sun-y:${state.sunY.toFixed(2)}%`,
|
|
`--hp-day-cycle-sun-opacity:${state.sunOpacity.toFixed(3)}`,
|
|
`opacity:${Math.min(1, Math.max(0, viewWeight)).toFixed(4)}`,
|
|
].join(';');
|
|
return html`<div class="hp-day-cycle-env" aria-hidden="true"
|
|
data-day-cycle-phase=${state.phase} data-day-cycle-source=${state.source}
|
|
style=${position}>
|
|
${PHASES.map((phase) => {
|
|
const palette = DAY_CYCLE_PALETTES[phase];
|
|
const background = `background:radial-gradient(ellipse at 50% 88%, ${palette.horizon} 0%, transparent 54%),linear-gradient(180deg, ${palette.top} 0%, ${palette.bottom} 100%);box-shadow:inset 0 0 90px ${palette.vignette}`;
|
|
return html`<div class="hp-day-cycle-bg phase-${phase} ${phase === state.phase ? 'active' : ''}"
|
|
data-day-cycle-layer=${phase} style=${background}>
|
|
<div class="hp-day-cycle-sun" style="background:radial-gradient(circle, ${palette.sun} 0%, transparent 67%)"></div>
|
|
</div>`;
|
|
})}${moon}
|
|
</div>`;
|
|
}
|