Stereo Field
stereo-fieldViewersWhere the sound sits between the speakers, and whether it survives a mono sum.
$ pnpm dlx shadcn@latest add @pluginui/core-stereo-fieldInstall
Copies the source into your project. Anything it depends on comes with it. Run this in your React project with shadcn initialized; no registry configuration is needed.
Pulls in
Install using the registry URL
$ pnpm dlx shadcn@latest add https://pluginui.com/r/core-stereo-field.jsonUsage
Connect the documented props to your application or host.
import { StereoField } from "@/components/ui/stereo-field"
// Parameter-side: an auto-panner's cursor, animated by whoever owns the LFO.
<StereoField pan={Math.sin(phase)} width={0.4} />
// Driven readings, when the engine already meters.
<StereoField pan={0} width={0.8} correlation={corr} balance={bal} mid={m} side={s} />
// A live pair in read-only mode; never connected or reconfigured.
<StereoField analyserLeft={left} analyserRight={right} />About Stereo Field
A single panel shows the parameter-side picture of a stereo image: an L-R field with a pan cursor, the width parameter as a spread around it, mid/side balance bars, and a correlation meter. The cursor is a reading, not a control. Pass an LFO phase each frame to show an auto-panner's motion; the host owns the clock, as with lfo-visualizer. Below it, a separate mark shows measured energy balance, which is not a pan-knob readback. A mono source panned to 0.5 by the constant-power law balances at 0.414. Both readings are correct about different things, and one mark could not show both without misrepresenting either the parameter or the signal. The correlation meter's lower half is tinted because the scale has asymmetric meaning: above zero the channels reinforce in a mono sum; at -1 they cancel, making the material disappear when anything downstream folds to mono. Pair it with lissajous-scope to see the same signal's shape. This component shows its numbers, not a goniometer.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| pan | number | 0 | Cursor position, -1 (hard left) to +1 (hard right). A parameter, not a measurement: animate it from an LFO phase and the auto-panner's motion draws itself. |
| width | number | 0 | Width parameter from 0 (a point at the cursor) to 1 (the whole field when centred), drawn as a symmetric spread. At the field's edges, a wide, hard-panned image appears asymmetrical because it cannot extend past L. |
| correlation / balance / mid / side | number | — | Precomputed readings, the driven form and the primary one. Resolved per field: anything supplied here wins over any live source, so a panel that knows its own correlation can still borrow the live mid/side. |
| analyserLeft / analyserRight | AnalyserNode | null | — | A live pair in read-only mode. The component never connects, disconnects or reconfigures a node and never builds an AudioContext. |
| getStereoData | (left: Float32Array, right: Float32Array) => boolean | void | — | Fill both arrays with the current frame and return true. The engine-agnostic form: a worklet or a test harness drives the meter with no Web Audio involved. Returning false is 'no data this frame'. |
| ballistics | { attack?: number; release?: number } | { attack: 0.35, release: 0.08 } | Needle time constants for live readings, in seconds. The default deliberately reverses the kit's meter default. On a correlation meter, the important movement is a drop toward antiphase, so the fast constant applies to downward travel. Driven values are never smoothed because they already represent the host's intended value; smoothing would make them lag behind the knob. |
| showCorrelation / showMidSide | boolean | true | Which readings are drawn. With both off the panel is the L-R field and the cursor alone, which is all an auto-panner face needs. |
| labels | [string, string] | ["L", "R"] | End captions for the field. |
| color | string | — | Override the accent colour for this instance. The warning tint is shared with gain-reduction-meter's hot zone and cannot be overridden, so one face cannot use different reds for the same warning. |
| height | number | 64 | Height of the L-R field in pixels. There is no layout width prop because `width` names the stereo-width parameter; the panel fills its container. |
Interaction
- Drag with pointer capture, so the gesture keeps tracking past the edge of the control.
- Shift while dragging for a fine pass; release it mid-gesture and coarse tracking resumes.
- Double-click resets to
defaultValue. - Arrow keys step normally, Shift+arrow steps finely, PageUp/PageDown jump by ten, Home/End go to the extremes.
- Proper
sliderandswitchroles with livearia-valuetext, so a screen reader announces the formatted value rather than the raw number. - The scroll wheel adjusts the value while the pointer is over the control; stepped ranges move at least one declared step per notch by default.