Match the desktop plot interactions in the web UI

- Wheel zoom around the cursor on both curve plots and the spectrogram:
  Ctrl zooms time only, Shift values only, scrolling over an axis zooms
  that axis; drag pans live; double-click resets. The zoom window survives
  redraws, overlay changes and resizes, and resets when units change.
- Guide and reference lines are painted in a uPlot draw hook, so a dragged
  reference line (now with a triangle handle and label) follows the cursor
  instead of jumping on release. Per-track integrated lines take the
  track's colour when overlaid.
- In-plot legend like pyqtgraph's: a swatch per track plus LRA / max dBTP.
- Metadata shows integrated loudness, LRA and max true peak (prefetched
  first) instead of debug rows; the file list shows each track's LUFS.
- UI, canvas and axis text prefer M PLUS 1 Code, else the system font.
- Spectrogram image is cached offscreen so panning is cheap; its tick
  labels adapt to the zoom level.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015UXA39Sh9coAx4FhRkd8R2
This commit is contained in:
2026-09-15 17:15:01 +09:00
parent 6ae4d5e8e3
commit aed2d54b45
4 changed files with 739 additions and 428 deletions
+3 -2
View File
@@ -32,7 +32,7 @@
<button id="refresh-plot" class="btn" type="button" title="Redraw from the computed results">Refresh</button>
<div class="separator"></div>
<button id="pick-files" class="btn primary" type="button">Add audio…</button>
<input id="file-input" type="file" accept=".mp3,.wav,.flac,.ogg,.oga,.m4a,.aif,.aiff,.opus" multiple hidden>
<input id="file-input" type="file" accept=".mp3,.wav,.flac,.ogg,.oga,.m4a,.aif,.aiff,.aifc,.opus" multiple hidden>
</div>
</header>
@@ -67,7 +67,7 @@
<section class="stage">
<div class="plot-head">
<h1 id="plot-title">No track loaded</h1>
<div id="legend" class="legend"></div>
<div class="plot-hint">Scroll to zoom · Ctrl: time only · Shift: values only · drag to pan · double-click to reset</div>
</div>
<div id="plot-host" class="plot-host">
@@ -79,6 +79,7 @@
and closing the tab discards it. Analysis runs at the file's native sample rate.</p>
</div>
<canvas id="heatmap" class="heatmap" hidden></canvas>
<div id="plot-legend" class="plot-legend" hidden></div>
</div>
<div class="statusbar">