Commit Graph
4 Commits
Author SHA1 Message Date
topkoaandClaude Opus 4.8 64b95d6f34 Persist per-pane framing across songs via durable slot keys
Per-pane overrides were keyed by an ephemeral per-instance id, so leaving a
song and opening another rebuilt the renderer with a new id and the pane's
framing was lost.

Key overrides by the durable split slot again ('main' | 'panel<idx>', via
_bgPanelKey) so the same slot means the same pane across songs, and persist
__panels to localStorage. Keep the anti-flicker fixes that were the actual
cause of the earlier dropdown churn (prune stale panes, rebuild only on a
pane-set change, never rebuild while the select is focused). The slot key is
latched to the last real slot so a transient null from panelIndexFor during
a song/layout transition can't flip it to 'main' and drop the override for a
frame; it resets in destroy() for instance reuse in another slot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-01 02:08:27 -04:00
topkoaandClaude Opus 4.8 6c42d83c31 Fix flickering / wrong panes in the wide-pane Target picker
The Target dropdown keyed panes off feedBackSplitscreen.panelIndexFor,
which can return the focused index for any canvas — so both split panes'
keys ping-ponged, rebuilding the <select> every frame (flicker) and
listing wrong/duplicate entries. The registry also never dropped panes
from a prior song or a closed split.

- Key each pane by a stable per-renderer-instance id (_paneUid, assigned
  once in init) instead of the split panel index.
- Prune panes not reported within ~1.5s (song change / split teardown).
- Mark the dropdown dirty only when the pane SET changes, not on every
  per-frame re-report, and skip rebuilding while the <select> is focused.
- Hide the Target row entirely when there's a single pane.
- Label panes by arrangement name, falling back to "Pane N".

Per-pane overrides are now session-only (keyed by ephemeral instance ids),
so they're no longer persisted to localStorage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-01 02:01:41 -04:00
topkoaandClaude Opus 4.8 9f0d48cb1f 3D highway wide-pane tuner: dismiss + per-pane targeting
Two usability gaps in the wide-pane framing tuner:

- No way to dismiss the panel. Add a × close button to the header and make
  the Shift+A shortcut open/close the panel (reveal/dismiss). The A/B
  enabled toggle now lives as a checkbox in the panel, so closing the panel
  no longer changes the framing state.

- Edits hit every split pane at once. Add a Target selector (All panes, or a
  specific pane labelled by its arrangement, e.g. "Panel 1 — Rhythm"). Per-
  pane edits write a sparse override map (__panels[key]); each renderer
  resolves the shared base with its own pane's overrides laid on top via
  _resolveTuneFor(paneKey), so one pane can be framed independently. Reset on
  a pane clears its override (re-inherits the base); Copy exports the resolved
  values for the selected target. The live readout is keyed per pane.

Panes are discovered from the existing per-panel key (_bgPanelKey /
feedBackSplitscreen.panelIndexFor) and self-register each frame for the
picker. Overrides persist to localStorage alongside the base.

Tests extended in tests/js/highway_3d_wide_fov.test.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-01 01:53:45 -04:00
3e3a98a0d0 Aspect-aware framing for ultra-wide 3D highway panes (#652)
* Add aspect-aware framing for ultra-wide highway panes

On a top/bottom 2-player split each 3D highway pane is full-width /
half-height (~32:9). The camera's vertical FOV was locked at a single
value, so at that aspect the horizontal cone ballooned past 130deg and
squeezed the fixed-width neck into a thin central sliver with large dead
margins on either side.

Add a "horizontal-FOV-hold" path: past a configurable start aspect the
effective vertical FOV is lowered so the horizontal cone stays roughly
constant, letting the neck fill a wide pane. At/under the start aspect it
is an exact no-op, so normal ~16:9 single-player and most 2x2 panes are
unchanged. Optional pose nudges (height / dolly / pitch / look-depth)
further flatten the view toward a low, immersive angle.

Everything is driven by a runtime bridge (window.__h3dAspectTune) with a
live tuner panel (Shift+A in the player) exposing every knob plus a live
aspect/FOV readout, localStorage persistence, and a Copy button. Toggling
the feature off restores the exact prior framing, so it doubles as an A/B
control. Shipped on by default for wide panes for testing feedback.

Source-pinned by tests/js/highway_3d_wide_fov.test.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: topkoa <topkoa@gmail.com>

* fix(highway_3d): ship wide-pane framing default-OFF with a coherent config

Review fixes for the aspect-aware framing. The first cut shipped
_ASPECT_DEFAULTS = { enabled:true, baseVfov:30, blend:0, minVfovDeg:36 },
which contradicted the PR's own "default off → byte-for-byte prior behaviour"
claim:

- enabled:true made the tune active for everyone, and baseVfov:30 forced every
  pane's vertical fov from 70° to 30° (normal single-player/2x2 panes included —
  a drastic global zoom, not the advertised no-op).
- blend:0 collapsed the Hor+ math back to base, so the actual horizontal-FOV-
  hold did nothing even on wide panes — the only net effect was the zoom.
- minVfovDeg:36 > baseVfov:30 was an inverted floor (clamped wide panes UP to
  36° rather than flooring a real reduction).

New defaults: { enabled:false, baseVfov:BASE_VFOV(70), blend:1,
minVfovDeg:HORPLUS_MIN_VFOV(28) }. Now:

- OFF by default → camUpdate passes a null tune → effectiveVfov returns
  BASE_VFOV → exact no-op on every pane (verified: 70° at 16:9 and 32:9).
- When a tester enables it (Shift+A), baseVfov==BASE_VFOV keeps normal/≤start
  panes at 70° (still a no-op there) and blend:1 makes the hold actually engage
  on genuinely wide panes (47.7° at 32:9, flooring toward 28° as aspect grows).
- minVfovDeg < baseVfov is a real floor.

Also bumps the localStorage key (h3d_aspect_tune → h3d_aspect_tune2) so a
machine that persisted the old broken default gets the corrected one, and adds
source-pin tests guarding default-off + the coherent base/blend/floor so this
can't silently regress to default-on again. The pose-nudge values are left as
the author's in-progress wide-pane look (dormant until enabled). 110/110 tests
pass; node --check clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: topkoa <topkoa@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
2026-06-30 17:36:32 +02:00