pnpm add @audio-ui/core
import { clipEnd, copyRange, coverClips, duplicateClip, FADE_SHAPES, /* … */ } from "@audio-ui/core/timeline";| Adapters | @audio-ui/react/timeline, @audio-ui/elements/piano-roll, @audio-ui/elements/timeline |
|---|---|
| Used by | use-timeline-cursor |
| Export | Kind | What it is |
|---|---|---|
ClipLimits | interface | What a clip edit keeps a clip within: the timeline's length, the shortest it may be, and its source's length. |
ClipValue | interface | A clip: a stretch of a source (a recording, a pattern) placed on the timeline. |
clipEnd | function | Where the clip ends on the timeline. |
copyRange | function | What the stretch from from to to holds of items: the part of each clip inside it, moved so the stretch starts at 0. |
coverClips | function | What a clip laid on a lane leaves of the clips already there: they are covered, not stacked. |
duplicateClip | function | A copy of the clip placed right after it, or as late as the timeline allows when there is not room for it. |
FADE_SHAPES | const | The fade shapes in the order a control steps through them. |
FadeShape | type | How a fade rises or falls: evenly, quick then slow, slow then quick, or eased at both ends. |
fadeGain | function | The gain a fade of shape has progress of the way through it, from 0 (silent) to 1 (full): the curve of a fade-in; a fade-out plays it backwards. |
insertTime | function | Opens a stretch length long at at: everything from there moves later, and a clip across at is cut in two around the gap. |
moveClip | function | Moves the clip to begin at start, keeping its length and its place in the source. |
nextFadeShape | function | The shape after shape, going round, for a control that steps through them. |
removeTime | function | Takes the stretch from from to to out of the timeline: what is in it goes, and everything after it moves back to close the gap. |
setClipFadeIn | function | Sets the fade-in's length, which cannot run into the fade-out. |
setClipFadeOut | function | Sets the fade-out's length, which cannot run into the fade-in. |
setClipFadeShape | function | Gives the fade at edge the shape shape. |
splitClip | function | Cuts the clip in two at at, a position on the timeline. |
trimClipEnd | function | Trims the clip's end to end, as far as the timeline and the source allow. |
trimClipStart | function | Trims the clip's start to start: what is cut off stays in the source, so the clip's content does not move on the timeline. |
ClipChangeEventDetails | type | What onValueChange receives with each change to a clip: what moved (target), for a move how far and over which lane, whether Alt asks for a copy, the reason ("drag", "keyboard", "input-change" or "double-click"), the event, and cancel() to refuse the change. |
ClipCommitEventDetails | type | What onValueCommitted receives once a gesture on a clip ends: what moved, the reason and the event behind it. |
ClipController | interface | What createClipController returns: the snapshot to draw from, and the presses, keys, typed values and fade shapes that move, trim and fade the clip, and select it. |
ClipOptions | interface | The options of createClipController: the clip and its selection, each held or controlled, the timeline's length, grid, steps and zoom, the shortest length, the source's length, and the callbacks. |
ClipSnapshot | interface | What a view draws a clip from: its value, whether it is selected, and what a drag is moving and by how much. |
ClipTarget | type | What a change to the clip moves. |
createClipController | function | A clip's behavior with no view attached: its span, held or controlled, moved, trimmed or faded by the pointer or the keys, and selected. |
keyTargets | function | The keys' targets for an edge or a clip, moved by the keyboard. |
laneUnder | function | The lane the pointer is over, if any: the element that marks itself as one. |
normalizeClip | function | The clip as the timeline holds it: finite, on the timeline, fades within its length. |
sameClip | function | Whether two clips hold the same values. |
wholeClip | function | The clip a timeline without one starts with: the whole of it, from the source's start. |
adjacentPoint | function | The nearest of points strictly after from (direction 1) or strictly before it (direction -1), or null when there is none that way: what jumping to the next or the previous locator, or cue, needs. |
createNavigatorController | function | The navigator's behavior: a bar with the stretch the viewport shows inside it, which a drag or a key moves. |
movedRange | function | Where part lands when moved by delta units from from, within the timeline. |
NavigatorController | interface | What createNavigatorController returns: the stretch the window shows, and the presses, keys, typed values and double click that move it. |
NavigatorMetrics | interface | How the viewport is scrolled and zoomed, as last laid out. |
NavigatorOptions | interface | The options of createNavigatorController: the timeline's length, how the viewport is laid out, the functions that scroll and zoom it, and the narrowest the window may be. |
NavigatorPart | type | The part of the navigator a gesture moves: one of its edges, or the window between them. |
rangeOfThumb | function | The stretch a window drawn from thumb[0] to thumb[1] px shows: thumbOf read back. |
thumbOf | function | The window as it is drawn on a bar bar px wide, its two edges in px, for the stretch range: never narrower than least, and inside the bar, at the end of the timeline too. |
visibleRange | function | The stretch of the timeline the viewport shows, in units. |
createTimelineController | function | The timeline's playback position and zoom, with no view attached: held, controlled or live, moved by a press, a drag, a key or an input, and zoomed. |
TimelineController | interface | What createTimelineController returns: the snapshot to draw from, and the presses, keys, typed values and zooms that move the playhead or the view. |
TimelineOptions | interface | The options of createTimelineController: the position and the zoom, each held, controlled or (the position) live, the timeline's length, grid and steps, the zoom's bounds, and the callbacks. |
TimelinePositionChangeEventDetails | type | What onPositionChange receives with each move of the playhead: the reason ("press", "drag", "keyboard" or "input-change"), the event, and cancel() to refuse the move. |
TimelinePositionCommitEventDetails | type | What onPositionCommitted receives once a move of the playhead ends: the reason and the event behind it. |
TimelineSelectionHandlers | interface | Listens to the stretch a Shift + drag on the ruler selects: set by the ruler. |
TimelineSnapshot | interface | What a view draws the timeline from. |
TimelineZoomChangeEventDetails | type | What onZoomChange receives with each zoom: the reason ("wheel", "drag", "keyboard", "input-change" or "double-click"), the event, and cancel() to refuse it. |
valueAtLane | function | The timeline's units under a point of lane, clamped to the timeline. |
createRangeController | function | A range's behavior with no view attached: its span on the timeline, held or controlled, moved or resized by its body or its edges, drawn across empty lane, and moved by the keys and inputs. |
drawnRangeWidth | function | How wide a range width px long is drawn, so that it keeps least px of room for its handles: from 2 * least px up, as long as it is, and under that it still grows with its length, at half the rate. |
RangeChangeEventDetails | type | What onValueChange receives with each change to a range: which edge moved, or "both", the reason ("drag", "draw", "keyboard" or "input-change"), the event, and cancel() to refuse the change. |
RangeCommitEventDetails | type | What onValueCommitted receives once a gesture on a range ends: which edge moved, the reason and the event behind it. |
RangeController | interface | What createRangeController returns: the snapshot to draw from, and the presses, draws, keys and typed values that move and resize the range. |
RangeOptions | interface | The options of createRangeController: the range, held or controlled, the timeline's length, grid, steps and zoom, the shortest length, whether it can be moved or drawn, and the callbacks. |
RangeSnapshot | interface | What a view draws a range from. |
rangeWidthOfDrawn | function | How long a range is, in px, when it is drawn drawn px wide. |
anchoredScroll | function | Where the viewport must scroll so anchor.value stays anchor.offset px from its start at the new zoom. |
clampZoom | function | Keeps zoom within its bounds; anything that is not a positive number is refused. |
valueAtOffset | function | The value under a point offset px from the viewport's start. |
ZoomAnchor | interface | A point held still through a zoom: a value, and how far from the viewport's start it sits, in px. |
bypassesGrid | function | Whether a gesture asks to ignore the grid: Cmd on a Mac, Ctrl elsewhere. |
Grid | interface | Grid lines step apart, starting from offset. |
nearestSnapPoint | function | The point of grid nearest value within its radius, or null when none is that close. |
SNAP_RADIUS_PX | const | How far from a snap point, in px, a dragged thing is pulled onto it. |
snapMove | function | Where something dragged from origin should land, given where the pointer would put it. |
snapRangeMove | function | Where one edge of a range dragged from origin, or the whole range with "both", should land when the pointer has moved it by delta: the dragged edge snaps the way anything dragged does, and the range keeps within the timeline and its minimum length. |
snapSpanMove | function | Where a span length long, dragged from origin, should start when the pointer would start it at target: either of its edges lands on a snap point within reach (the nearer one wins), or else its start snaps the way anything dragged does. |
snapToGrid | function | The snap point within reach of value, or else the grid line nearest it. |
withoutSnapPoints | function | The grid without the given points, so something dragged is not pulled onto its own edges. |
withSnapRadius | function | The grid with its points pulling from radius units away, so a gesture can set it from its own zoom. |
createTrackController | function | A track's height, with no view attached: what a drag, a key, an input or a double click asks of it. |
TrackController | interface | What createTrackController returns: the snapshot to draw from, and the presses, keys, typed values and reset that ask for a height. |
TrackHeightChangeEventDetails | type | What onHeightChange receives with each resize of a track: the reason ("drag", "keyboard", "input-change" or "double-click"), the event, and cancel() to refuse it. |
TrackHeightCommitEventDetails | type | What onHeightCommitted receives once a resize ends: the reason and the event behind it. |
TrackOptions | interface | The options of createTrackController: the height its parent holds, its bounds and steps, how to measure it, and the callbacks. |
TrackSnapshot | interface | What a view draws a track's resize handle from: whether a resize is under way. |
createWheelZoom | function | A wheel zoom around the pointer. |
WHEEL_ZOOM_SENSITIVITY | const | How far one pixel of wheel delta zooms, as an exponent. |
WheelZoomController | interface | What createWheelZoom returns: the wheel handler, setOptions, and dispose. |
WheelZoomOptions | interface | The options of createWheelZoom: the timeline's length, the zoom as drawn, where its start sits, and the function that applies a zoom. |
Usage
A timeline is made of several controllers, each with no view attached and each following the contract every controller shares, and of plain functions that edit clips. Positions are in the timeline's own units, seconds or beats, and the zoom is in pixels per unit.
The playhead and the zoom
createTimelineController holds the playback position and the zoom: held, controlled with position and zoom, or live with source, which it follows without a render. A press or a drag on the ruler or a lane moves the position, onto a snap point of the grid within a few pixels, the keys step it by step and largeStep, and a Shift + drag on the ruler selects a stretch, reported to the handlers given to it. A zoom of null fits the timeline to its width.
createWheelZoom zooms with the wheel around the pointer, holding the value under it still, once per frame. A trackpad's pinch zooms by the square of the fingers' spread, so a few pinches go from the whole timeline to its finest zoom, and no frame zooms more than twice in or half out, so a mouse's notch never jumps further; anchoredScroll is where to scroll so a value stays put through a zoom, and clampZoom keeps a zoom within its bounds.
Clips
A clip is a stretch of a source, a recording or a pattern, placed on the timeline: where it starts, how long it is, where in the source it begins (offset), and its fades. Every edit is a plain function that returns a new clip:
import { moveClip, setClipFadeIn, splitClip, trimClipStart } from "@audio-ui/core/timeline";
const clip = { start: 4, length: 8, offset: 0, fadeIn: 0, fadeOut: 0 };
const limits = { duration: 64, sourceLength: 8 };
trimClipStart(clip, 5, limits); // { start: 5, length: 7, offset: 1, … }: the content stays put
splitClip(clip, 6); // two clips, the second reading the source from 2
moveClip(clip, 10, limits); // { start: 10, … }
setClipFadeIn(clip, 2); // a fade-in that cannot run into the fade-outduplicateClip, trimClipEnd, setClipFadeOut and setClipFadeShape complete them; a fade's shape is one of FADE_SHAPES (linear, fast, slow, smooth), and fadeGain is its gain partway through. On a lane, coverClips lays a clip over others the way an arrangement does, covering rather than stacking them, and insertTime, removeTime and copyRange edit a stretch of time across every clip in it.
createClipController is a clip's gestures: moved by its body, trimmed by its edges, faded by its fade handles, from the pointer or the keys, and selected.
Ranges, the navigator and tracks
createRangeControlleris a span on the timeline, such as the loop or a selection: moved or resized by its body or its edges, drawn across empty lane, and moved from the keys and inputs.createNavigatorControlleris the overview bar with the visible stretch inside it: moving the window scrolls, moving an edge zooms and holds the other edge still.visibleRange,thumbOfandrangeOfThumbconvert between them.createTrackControllerreports what a drag, a key, an input or a double click asks of a track's height; the parent holds the height and sets it.
Snapping
A Grid is lines step apart from an offset, with snap points such as clip edges that pull from SNAP_RADIUS_PX away. snapToGrid(value, grid) gives the snap point within reach or the nearest line, snapMove, snapSpanMove and snapRangeMove place something dragged, and bypassesGrid(event) says when a gesture asks to ignore the grid: Cmd on a Mac, Ctrl elsewhere.
The Arrangement draws these in React.