Lab

Envelope

The <audio-ui-envelope> custom element of @audio-ui/elements: its attributes, its parts and a live preview.

<audio-ui-envelope> is a breakpoint envelope editor with role="group". Points are dragged to move, added with a double click on the graph, and removed with a double click, Alt + click or Delete. Each segment has a curve handle at its midpoint, and Alt + drag on the graph bends the segment under the pointer. The points share one tab stop: Page Up and Page Down (or Home and End) move between them, and the arrow keys move the focused point. Points and segment handles are generated, from a <template> when one is provided:

Usage

The styles read the theme's CSS variables, which Styling sets.

<style>
  audio-ui-envelope {
    display: block;
    width: 100%;
    max-width: 28rem;
    height: calc(var(--spacing, 0.25rem) * 40);
    border-radius: calc(var(--radius, 0.625rem) - 2px);
    background: var(--muted, oklch(0.97 0 0));
  }

  audio-ui-envelope-fill {
    color: var(--primary, oklch(0.205 0 0));
    opacity: 0.15;
  }

  audio-ui-envelope-line {
    color: var(--primary, oklch(0.205 0 0));
    stroke-width: 2px;
  }

  audio-ui-envelope-point {
    box-sizing: border-box;
    width: calc(var(--spacing, 0.25rem) * 3);
    height: calc(var(--spacing, 0.25rem) * 3);
    border: 2px solid var(--primary, oklch(0.205 0 0));
    border-radius: var(--radius, 0.625rem);
    background: var(--background, oklch(1 0 0));
    cursor: grab;
    outline: none;
  }

  audio-ui-envelope-point:focus-visible,
  audio-ui-envelope-point[data-dragging] {
    background: var(--primary, oklch(0.205 0 0));
  }

  audio-ui-envelope-segment {
    width: calc(var(--spacing, 0.25rem) * 2);
    height: calc(var(--spacing, 0.25rem) * 2);
    border-radius: var(--radius, 0.625rem);
    background: var(--muted-foreground, oklch(0.556 0 0));
    opacity: 0.5;
    cursor: ns-resize;
    outline: none;
  }

  audio-ui-envelope-segment[data-flat] {
    display: none;
  }
</style>

<audio-ui-envelope aria-label="Amp envelope" default-value="0 0, 0.12 1, 0.35 0.6 0.4, 0.75 0.6, 1 0">
  <audio-ui-envelope-graph>
    <audio-ui-envelope-fill></audio-ui-envelope-fill>
    <audio-ui-envelope-line></audio-ui-envelope-line>
  </audio-ui-envelope-graph>
  <audio-ui-envelope-segments></audio-ui-envelope-segments>
  <audio-ui-envelope-points></audio-ui-envelope-points>
</audio-ui-envelope>

<script type="module">
  import "@audio-ui/elements/envelope";

  const envelope = document.querySelector("audio-ui-envelope");
  envelope.addEventListener("change", (event) =>
    console.log(event.detail.value)
  );
</script>

API reference

pnpm add @audio-ui/elements
import "@audio-ui/elements/envelope";
ExportKindWhat it is
ENVELOPE_TAGSconstThe names the envelope's elements are registered under, frozen: a page cannot rename them by accident.
EnvelopeChangeEventtypeFired once an interaction that changed the points ends.
EnvelopeElementclassThe root of a breakpoint envelope editor, with role="group".
EnvelopeElementEventMapinterfaceThe events an envelope fires, as addEventListener types them.
EnvelopeEventDetailinterfaceWhat an envelope's input and change events carry, besides the envelope itself as their target.
EnvelopeFillElementclassThe area under the curve, in currentColor.
EnvelopeGraphElementclassThe drawing surface, filling the envelope (position: absolute; inset: 0) and containing the line and the fill.
EnvelopeInputEventtypeFired on every change.
EnvelopeLineElementclassThe curve through the points, in currentColor, with a stroke width that stays constant as the graph scales.
EnvelopePointElementclassA draggable handle for the point at index, positioned with left and bottom.
EnvelopePointsElementclassGenerates an <audio-ui-envelope-point> per point, in x order, from its <template> when present.
EnvelopeSegmentElementclassA curve handle at the midpoint of the segment that starts at point index, a role="slider" from -1 to 1.
EnvelopeSegmentsElementclassGenerates an <audio-ui-envelope-segment> per segment, from its <template> when present.

Props · 9

input and change carry { value, reason, index }, with reason one of drag, keyboard, add, remove or curve. The getPointValueText(point, index) and getCurveValueText(curve, index) properties customize aria-valuetext.

PartDescription
<audio-ui-envelope-graph>The drawing surface, filling the envelope. A double click adds a point; carries data-blocked briefly when adding is refused
<audio-ui-envelope-line>The curve through the points, in currentColor, with a constant stroke width set by stroke-width
<audio-ui-envelope-fill>The area under the curve, in currentColor
<audio-ui-envelope-points>Generates an <audio-ui-envelope-point> per point. label names them, with {n} and {count} placeholders (Point {n} of {count} by default)
<audio-ui-envelope-point>A slider on the point's level, positioned with left and bottom. Carries data-dragging, data-removable, and data-blocked briefly when removal is refused
<audio-ui-envelope-segments>Generates an <audio-ui-envelope-segment> per segment. label names them (Curve {n} by default)
<audio-ui-envelope-segment>A slider on the segment's curve, from -1 to 1, at its midpoint. Drag or Up and Down to bend; double click or Delete to straighten. Carries data-flat when the segment cannot bend

The same control in React, and its parts' props: Envelope.

Built by Ouest Labs, the source code is available on GitHub.
RSS