Skip to content

v7.1.2

Latest

Choose a tag to compare

@naomiaro naomiaro released this 14 Feb 07:47
· 21 commits to main since this release

New Features

  • Horizontal virtual scrolling — Only canvas chunks visible in the scroll viewport (+ 1.5x overscan buffer) are mounted. Eliminates canvas memory limits for long files (previously crashed at ~16,000px). Affects Channel, TimeScale, and SpectrogramChannel.
  • Web worker peak generationWaveformData is generated in a web worker at load time, then resample() provides near-instant zoom changes. Any clip with an audioBuffer gets worker treatment automatically.
  • useDynamicTracks hook — Imperative API for adding tracks at runtime (drag-and-drop, file picker). Creates placeholder tracks immediately while decoding runs in parallel.
  • useChunkedCanvasRefs hook — Standardized canvas ref management for chunked rendering (extracted from Channel, TimeScale, SpectrogramChannel).
  • useVisibleChunkIndices hook — Viewport-aware chunk index computation, shared across all canvas-based components.
  • spectrogramConfig on CreateTrackOptions — Per-track spectrogram configuration at creation time.

Performance

  • Eliminated layout thrashing during playback — animation loops no longer trigger React state updates per frame
  • Removed per-frame setCurrentTime from animation loops — uses refs for 60fps DOM updates
  • startTransition for zoom — zoom changes no longer block the animation loop
  • Throttled viewport context updates — 100px scroll threshold prevents excessive re-renders
  • visibleChunkKey optimization — avoids redundant canvas redraws when scroll position changes within the same chunk set

Bug Fixes

  • Fixed spectrogram rendering with virtual scrolling — chunks were rendering the first segment repeatedly at high zoom because pixel offsets were computed by summing widths from index 0 instead of using actual chunk numbers
  • Fixed stereo spectrogram channel starvation — bottom channel rendered black during scrolling because ch0's background batches consumed all rendering time before ch1 got any visible chunks. Two-phase rendering now processes visible chunks for ALL channels first.
  • Fixed stale canvas registration race condition — cleanup and registration effects merged into a single effect so onCanvasesReady always receives a clean list
  • Fixed canvas notification bug — provider was never notified when canvases were removed without new ones mounting (tautological condition from ref mutation before comparison)
  • Fixed worker canvas unregistration on scroll — prevented spurious unregister/re-register cycles during viewport changes
  • Fixed layout shift on track loaduseDynamicTracks creates placeholder tracks immediately

Refactoring

  • Peaks, Bits, PeakData types moved to @waveform-playlist/core — re-exported from webaudio-peaks for backwards compatibility
  • MAX_CANVAS_WIDTH moved to @waveform-playlist/core — shared between ui-components and spectrogram packages
  • Shared animation frame loopuseAnimationFrameLoop hook extracted and used by both playlist providers
  • ESLint baseline — flat config with TypeScript + React Hooks checks across all packages
  • extractChunkNumber helper — parses chunk index from canvas IDs for correct virtual scrolling offsets
  • renderBackgroundBatches helper — deduplicated idle-callback batching between FFT and display-only rendering paths