player bar: a complete waveform arrives as one motion instead of popping

Chosen on waveform-arrive.html (M2, direct morph, 1000ms): when a track
has its whole waveform at once — a local file, a fully-cached stream, or
the final decode replacing a stream's progressive peaks — every bar eases
from whatever the lane currently shows straight into the new shape, all
together. From the resting dots that reads as a uniform grow; from a
mid-sweep swell or the previous track's bars it is literally one waveform
transforming into another. The streaming rise keeps its left-to-right
story untouched; the morph fires only on a peaks swap at coverage 1, and
never on a resize, which re-lays the same shape and stays instant.

The canvas keeps a record of what it actually painted last frame — dots,
swell, rise, morph or settled — so the morph always starts from the truth
on screen, and the fade colours (accent, boundary blend, hover wash) stay
live through it. The rail mirrors the motion in CSS: an `arriving` class
carries the same 1000ms house-ease height transition, placed after the
rise rule so a stream's final decode arrives on this ease too.

Measured live on a cached start: bar heights walked 5.2 → 8.2 → 10.6 →
12.3 → 13.6 → 14.6 → 15.0 and settled at 15.1 at the 1000ms mark — the
ease-out curve, frame by frame.
This commit is contained in:
KeelrLeek committed 2026-08-03 16:46:37 -05:00
1 parent 4c9a6e312a
commit 1765de65cf
3 files changed
+119 -11

No files matched your search

+7
View File
@@ -47,6 +47,13 @@ export const SWELL_AMP_PX = 7; // crest lift, playbar px (rail scales ×1.6)
export const SWELL_WIDTH_BARS = 54; // gaussian width of the crest
export const RISE_MS = 2000; // one bar, floor → full height
export const RISE_CADENCE_MS = 40; // gap between one bar starting and the next
/** The ARRIVAL morph — chosen on waveform-arrive.html (M2, direct morph,
* 2026-08-03): when a COMPLETE waveform lands (local track, cached stream,
* the final decode replacing a stream's progressive peaks), every bar eases
* from whatever the lane currently shows — resting dots, a mid-sweep swell,
* the previous shape — straight into the new one, all at once, one motion.
* The streaming rise keeps its left-to-right story; this is only coverage 1. */
export const ARRIVE_MS = 1000;
/** Resting/queued bars render the muted grey at this opacity — the rail's
* pending dim, shared so the two lanes' dots match. */
export const PENDING_ALPHA = 0.45;