fix(mood): keep the Dark/Light grade applied through altitude morphs

The mood grade was dropped while a morph played (busy): the WebGL canvas set
filter 'none' and the fallback set #vid's filter 'none' on morph load, so the
transition showed ungraded and the grade snapped back only on landing. Now the
grade rides through the morph on both paths (the painterly DREAM stays off mid-
morph, as before, to keep it crisp). +1 e2e (mood-grade.spec.ts).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-07-02 05:38:19 -07:00
parent f6b45b6cd7
commit 2f8641cb28
2 changed files with 54 additions and 3 deletions
+8 -3
View File
@@ -451,11 +451,13 @@ function paintLoop() {
if (paint.width !== w || paint.height !== h) { paint.width = w; paint.height = h; }
gl.viewport(0, 0, w, h);
try { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, src); } catch (_) {}
// No painterly restyle during a ring transition (busy) — show it raw.
// No painterly DREAM during a ring transition (busy) — show the morph crisp.
// The Dark/Light mood GRADE, however, must ride through the transition too
// (else the morph shows ungraded and the grade snaps back only on landing).
gl.uniform1f(uAmt, busy ? 0 : dreamIntensity);
gl.uniform2f(uTexel, 1 / w, 1 / h);
gl.drawArrays(gl.TRIANGLES, 0, 3);
paint.style.filter = busy ? "none" : gradeFilter;
paint.style.filter = gradeFilter;
}
// Animate per-frame: re-place keyframed tracks AND re-evaluate time-windowed
// labels (a label enters/leaves frame as the loop plays) against playback time.
@@ -983,7 +985,10 @@ function rebuildSegment(lo, enteredFrom) {
overlay.style.opacity = "0";
affectLayer.style.opacity = "0";
tint.style.opacity = "0";
vid.style.filter = "none";
// WebGL path: the graded canvas sits on top, so #vid stays raw (no double-grade).
// Fallback path: #vid IS the visible surface, so it must carry the mood grade
// through the morph (setting "none" here was the "morph ignores Mood" bug).
vid.style.filter = paintOK ? "none" : gradeFilter;
vid.loop = false;
if (vid.dataset.morph !== file) {
vid.dataset.morph = file;