Sun rays: brighter, and a hard 3 degree threshold with a 2 s fade

Owner 2026-08-03: «лучи поярче, иногда плохо видны. Убрать плавное
затухание — появляться и исчезать анимацией в 2 секунды при переходе
через 3 градуса над горизонтом».

RAY_MAX_ALPHA 0.18 -> 0.30: checked against both hard cases, a daylight
sun on white paper and a low sun over the dark glow canvas
(demo/shot_sun_bright.mjs writes the pair).

The gradual ramp-in over the first ~2 degrees is gone. rayAlpha() is now a
threshold: 0 below RAY_ELEVATION_MIN (3), rayPeakAlpha(cloud) at or above
it — cloud cover stays the only multiplier. Crossing it animates the
LAYER, never the geometry: <g class='sunlayer'> fades in/out over exactly
RAY_FADE_MS = 2 s (hp-sunfade-in / hp-sunfade-out), and the card keeps the
group mounted with .out for those two seconds so the dissolve can play at
all. prefers-reduced-motion skips it. Every other reason to drop the
wedges — editor, feature off, night, rain — stays instant.

Units: rayAlpha rewritten (ramp tests dropped), raysVisible/rayPeakAlpha/
RAY_MAX_ALPHA covered. Smoke: smoke_sun gains a threshold section (8 of
its checks fail on the previous build). docs/SUN.md + TESTING.md updated.
This commit is contained in:
houseplan dev
2026-08-03 22:25:03 +03:00
parent bb4d4e1f6e
commit 79142d9334
11 changed files with 399 additions and 82 deletions
+27 -3
View File
@@ -111,9 +111,33 @@ room's polygon (`polyclip` intersection, the same dependency
lengths: ~2.5 at sunrise/sunset tapering to ~0.8 at the zenith
(`0.8 + 1.7·(1 − elevation/90)^1.6`). A linear gradient runs bright at
the window and dissolves inward; the color is warm orange while
`elevation < 10°` and neutral by day; peak opacity is modest (~0.18 —
two overlapping wedges never exceed a readable ceiling). Near the
horizon the opacity ramps in over the first ~2° so wedges never pop.
`elevation < 10°` and neutral by day; peak opacity is `RAY_MAX_ALPHA`
= 0.30 (owner 2026-08-03: «лучи поярче, иногда плохо видны» — raised
from 0.18; two overlapping wedges still stay under a readable ceiling
on white paper and on the dark glow canvas alike).
### The 3° threshold and the 2-second fade
Wedge opacity does NOT depend on elevation any more — the old ramp-in
over the first ~2° is gone. The contract (owner 2026-08-03) is a hard
threshold:
- `elevation < 3°` → NO rays at all;
- `elevation ≥ 3°` → rays at full strength (`rayPeakAlpha`, cloud cover
being the only multiplier).
Crossing the threshold is animated, but on the LAYER, never on the
geometry: the `<g class="sunlayer">` fades in with `hp-sunfade-in` and
out with `hp-sunfade-out`, both exactly 2 s (`RAY_FADE_MS` in
`src/sun.ts` must stay in sync with `styles.ts`). To let the fade-out
play at all, the card keeps the layer mounted with `.out` for those two
seconds and only then drops it. `prefers-reduced-motion: reduce` skips
the animation entirely — the rays are simply there or simply gone.
Everything else that removes wedges — leaving view mode, switching the
feature off, night (`elevation ≤ 0`), rain — is instant: those are not
threshold crossings, and a wedge lingering while you enter the editor
would just be a bug.
Layer order: ABOVE room fills (and the glow layer), BELOW devices and
labels (those live in the HTML `devlayer` anyway). Night
+9
View File
@@ -931,6 +931,15 @@ require hands on real hardware — they remain for the human pass.
- [ ] Wedge direction follows the compass; length grows toward
sunrise/sunset and shrinks toward noon; every wedge is clipped by its
room polygon; night = no wedges at all
- [ ] Brightness + the 3° threshold (2026-08-03): wedges are visibly brighter
(peak alpha 0.30, was 0.18) yet still readable over white paper AND the
dark glow canvas; there is NO gradual ramp near the horizon — below 3°
no rays at all, at/above 3° full strength; crossing the threshold fades
the whole layer in/out over exactly 2 s (CSS on `.sunlayer`, the
geometry never moves), and `prefers-reduced-motion` makes it instant.
Every other way of losing the wedges (editor, feature off, night, rain)
stays instant [auto: smoke_sun «the 3° threshold» + unit rayAlpha/
raysVisible/rayPeakAlpha; shots: demo/shot_sun_bright.mjs]
- [ ] Weather entity (optional, global): cloudy fades the wedges, rain/snow
removes them, a dead/unknown weather sensor changes nothing
- [ ] Sun geometry recomputes ONLY when the sun attributes or the config