Envelope Display
envelope-displayViewersThe filled shape is the envelope; the three handles are the envelope. Drag the peak to set attack, the knee to set decay and sustain together, the tail to set release. Every handle is focusable and steps with the arrow keys. The time axis is square-root scaled, because a linear one crushes every millisecond attack into the first few pixels.
Bone / Studio
Loading interactive preview…
Planar / Flat
Loading interactive preview…
Midnight / Minimal
Loading interactive preview…
Ember / Vintage
Loading interactive preview…
Ink / Studio
Loading interactive preview…
Mint / Flat
Loading interactive preview…
Install
Copies the source into your project. Anything it depends on comes with it.
$ pnpm dlx shadcn@latest add @pluginui/core-envelope-displayPulls in
knob-coreuse-surface-pointeruse-first-interactioncontrol-theme
First time? Add the registry to your components.json once:
{
"registries": {
"@pluginui": "https://pluginui.com/r/{name}.json"
}
}Usage
Connect the documented props to your application or host.
import { EnvelopeDisplay } from "@/components/ui/envelope-display"
<EnvelopeDisplay
defaultValue={{ attack: 0.01, decay: 0.2, sustain: 0.6, release: 0.4 }}
onChange={(adsr) => voice.setEnvelope(adsr)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | { attack, decay, sustain, release } | — | Controlled envelope. Times in seconds, sustain 0..1. |
| defaultValue | ADSR | { 0.01, 0.2, 0.6, 0.4 } | Starting envelope, and the per-handle double-click reset target. |
| onChange | (value: ADSR) => void | — | Fires on every edit. |
| onChangeEnd | (value: ADSR) => void | — | Fires once when a drag finishes. |
| ranges | EnvelopeRanges | — | Per-segment bounds. Defaults: attack and decay 1 ms–4 s, sustain 0–1, release 1 ms–8 s. |
| curve | "linear" | "exponential" | "linear" | Render the attack and decay segments as ramps or as curves. |
| height | number | 160 | Display height in pixels; width defaults to 100%. |
| showGrid | boolean | true | Draw the horizontal level gridlines. |
| showSegmentLabels | boolean | true | Draw the A / D / S / R summary strip underneath. |
| inset | boolean | false | Recess the plot into its host panel with a soft inner shadow under the top edge, built from the border token. Use it with a framed host; EnvelopeEditor sets it when frame is on. |
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.