hero: the dispersion ring trails the reveal wave on its own delayed clock

The chromatic flare front now launches Flare lag seconds (0.2) after
the reveal front and sweeps the already-revealed field behind it as a
second pass, instead of riding fused to the reveal edge.

Claude-Session: https://claude.ai/code/session_01YBoaBEt3gynzTwogBFtn4B
This commit is contained in:
Tanish Manku committed 2026-09-10 23:23:20 -07:00
1 parent 48fc7c190c
commit 147730c905
2 files changed
+24 -6

No files matched your search

@@ -184,7 +184,15 @@ export const galaxyMotionTuner = defineTunables(
max: 0.15,
step: 0.002,
default: 0.05,
info: "Dispersion flare riding the wave front — cards flash chromatic as the reveal crosses them.",
info: "Dispersion flare of the chromatic ring trailing the reveal wave — cards flash as it crosses them.",
},
waveLag: {
label: "Flare lag s",
min: 0,
max: 1,
step: 0.05,
default: 0.2,
info: "How far behind the reveal front the dispersion ring launches — it sweeps the already-revealed field as a second pass.",
},
perfFloor: {
label: "FPS floor",
@@ -745,6 +745,12 @@ function GalaxyScene({
(introClock.t - iv.cardsAt) / Math.max(0.1, mv.introDur),
);
const waveEase = easeOutCubic(rollT);
// The dispersion ring launches on its own delayed clock, trailing the
// reveal front and sweeping the already-revealed field behind it.
const flareT = clamp01(
(introClock.t - iv.cardsAt - mv.waveLag) / Math.max(0.1, mv.introDur),
);
const flareEase = easeOutCubic(flareT);
const burstT = clamp01(
(introClock.t - iv.cardsAt) / Math.max(0.1, mv.burstDur),
);
@@ -1126,13 +1132,17 @@ function GalaxyScene({
// dispersion flash riding the front itself (waveG).
let waveK = 1;
let waveG = 0;
if (rollT < 1) {
if (rollT < 1 || (flareT > 0 && flareT < 1)) {
const rr = L.b * (L.thetaBirth + c * (L.thetaExit - L.thetaBirth));
const waveR = waveEase * L.b * L.thetaExit;
const band = Math.max(1, mv.waveBand);
waveK = clamp01((waveR - rr) / band + 1);
const fr = (rr - waveR) / band;
waveG = Math.exp(-fr * fr);
if (rollT < 1) {
const waveR = waveEase * L.b * L.thetaExit;
waveK = clamp01((waveR - rr) / band + 1);
}
if (flareT > 0 && flareT < 1) {
const fr = (rr - flareEase * L.b * L.thetaExit) / band;
waveG = Math.exp(-fr * fr);
}
}
const ready = videos[card.clip].readyState >= 2 ? 1 : 0;