Machine
Machines: an animation as a value. A machine is what an animation does each frame, apart from what
drives it: start() it, and the step it returns takes each frame's dt, in seconds, and gives that
frame, { value, done }. Each run has its own state, so one machine can run any number of times.
- Build one with a constructor:
tween,spring,chase,decay,inertia,animate,keyframes; for a bag of values,springValues,inertiaValues,animateValues,springBlendandkeyframesValues. Or withmake, for a motion of your own. - Compose with
map,concat,concatAll,forever,delay,holdAfter,startAt,clampDtandwithSpan. A machine isPipeable:m.pipe(Machine.delay(0.1)). Never spread one, which loses what makes it a machine. - Run one on the Frame loop with
run, which steps every running machine in one pass a frame, or as aStreamover the Clock's ticks withtoStream. Both give the same frames.
import * as Machine from "@wardic/core/Machine"
const fadeIn = Machine.tween(0, 1, { duration: 0.3, ease: "easeOut" }).pipe(Machine.delay(0.1))
// On the Frame loop, each Frame drawn:
yield* Machine.run(fadeIn, (frame) => {
draw(frame.value)
})
// Or stepped by hand:
const step = fadeIn.start()
step(1 / 60) // { value: 0, done: false }: still in its delayClasses
OptionError
Options an animation can't take, a negative duration say: its message names the field and what it
expected, Expected a value greater than 0 then at ["stiffness"]. Thrown as the animation is
built or started: a bug to fix, not a failure to handle. Machine.OptionError.
Extends
YieldableError<this> &object&Readonly<{message:string; }>
Constructors
Constructor
new OptionError(args): OptionError;Parameters
args
message
string
Returns
Inherited from
Data.TaggedError("OptionError")<{ readonly message: string }>.constructor
Properties
message
message: string;Inherited from
Data.TaggedError("OptionError").message
Interfaces
AnimateOptions
Options accepted by animate and animateValues.
Extends
Properties
delay?
readonly delay?: number;Delay before the animation starts, in seconds. With animate's repeat / repeatType, or across
keyframes' stops, it holds once, before the first Interval: Machine.delay.
Inherited from
duration?
readonly duration?: number;Seconds it takes. Default 0.3.
Inherited from
ease?
readonly ease?: Definition;How it eases, as Motion's ease: one of Motion's names ("easeOut"), a cubic Bézier's four numbers
([0.25, 0.1, 0.35, 1]), or a function. Default linear.
Inherited from
repeat?
readonly repeat?: number;How many more times it plays after the first: a whole number, or Infinity for ever. Default 0.
Each starts the moment the one before ends, or repeatDelay after; delay holds once, before the
first.
Inherited from
repeatDelay?
readonly repeatDelay?: number;Seconds between plays, as Motion's repeatDelay. Default 0. Each play but the last holds where it
ended for this long; with an infinite repeat, every play does.
Inherited from
repeatType?
readonly repeatType?: "reverse" | "loop" | "mirror";How every other repeat runs, as Motion's repeatType. Default "loop".
"loop": each run starts atfromagain."reverse": every other run plays backwards in time, fromtotofromon the easing's curve reversed: aneaseOutrun comes back easing in."mirror": every other run plays fromtotofromon the same easing: aneaseOutrun comes back easing out.
Inherited from
reverse?
readonly reverse?: boolean;Plays it from to back to from; keyframes, through their stops from last to first. Default false.
Inherited from
DecayOptions
A decay's options: how quickly it slows, when it rests, and a delay. A bag is read once and kept by its identity: one changed after it's handed over isn't seen, so pass a new one.
Properties
delay?
readonly delay?: number;Delay before the animation starts, in seconds.
friction?
readonly friction?: number;How quickly it slows: higher stops sooner. Default 3.
restSpeed?
readonly restSpeed?: number;At rest below this speed, per second. Default 0.1.
InertiaEdges
An axis's edges for inertiaVec: either may be left out.
Properties
max?
readonly max?: number;min?
readonly min?: number;InertiaOptions
An inertia's options: how far it glides and how it eases out, its edges and the spring back from
them, and where it rests. Times in seconds, where Motion's timeConstant is in milliseconds. A bag
is read once and kept by its identity: one changed after it's handed over isn't seen, so pass a new
one.
Extended by
Properties
bounceDamping?
readonly bounceDamping?: number;The bounce spring's damping. Default 10.
bounceStiffness?
readonly bounceStiffness?: number;The bounce spring's stiffness at an edge. Default 500.
max?
readonly max?: number;min?
readonly min?: number;The edges: past one, the glide springs back to it. None by default.
modifyTarget?
readonly modifyTarget?: (ideal) => number;Moves where the glide rests, called once with where it would: snapping a flick to a grid, say.
Parameters
ideal
number
Returns
number
power?
readonly power?: number;How far the glide carries, as a multiple of the velocity: it rests at initial + power × velocity. Default 0.8.
restDelta?
readonly restDelta?: number;The glide is done within this of where it rests, and the bounce within this of its edge. Default 0.5.
restSpeed?
readonly restSpeed?: number;The bounce rests below this speed, per second. Default 2.
timeConstant?
readonly timeConstant?: number;The glide's time constant, in seconds: it eases out as e^(−t / timeConstant). Default 0.325.
InertiaValuesOptions
inertiaValues' options: InertiaOptions, each key's velocity when it has none of its own, and a delay.
Extends
Properties
bounceDamping?
readonly bounceDamping?: number;The bounce spring's damping. Default 10.
Inherited from
bounceStiffness?
readonly bounceStiffness?: number;The bounce spring's stiffness at an edge. Default 500.
Inherited from
InertiaOptions.bounceStiffness
delay?
readonly delay?: number;Seconds each key holds where it starts before it glides. Default 0.
max?
readonly max?: number;Inherited from
min?
readonly min?: number;The edges: past one, the glide springs back to it. None by default.
Inherited from
modifyTarget?
readonly modifyTarget?: (ideal) => number;Moves where the glide rests, called once with where it would: snapping a flick to a grid, say.
Parameters
ideal
number
Returns
number
Inherited from
power?
readonly power?: number;How far the glide carries, as a multiple of the velocity: it rests at initial + power × velocity. Default 0.8.
Inherited from
restDelta?
readonly restDelta?: number;The glide is done within this of where it rests, and the bounce within this of its edge. Default 0.5.
Inherited from
restSpeed?
readonly restSpeed?: number;The bounce rests below this speed, per second. Default 2.
Inherited from
timeConstant?
readonly timeConstant?: number;The glide's time constant, in seconds: it eases out as e^(−t / timeConstant). Default 0.325.
Inherited from
velocity?
readonly velocity?: number;A key's velocity when velocity gives it none, per second. Default 0.
InertiaValuesStart
inertiaValues' run: each key's velocity, else the options', per second.
Properties
velocity?
readonly velocity?: Readonly<Record<string, number>>;InertiaVecOptions
Options for inertiaVec: InertiaOptions for both axes, with each axis's edges.
Extends
Omit<InertiaOptions,"min"|"max">
Properties
bounceDamping?
readonly bounceDamping?: number;The bounce spring's damping. Default 10.
Inherited from
bounceStiffness?
readonly bounceStiffness?: number;The bounce spring's stiffness at an edge. Default 500.
Inherited from
InertiaOptions.bounceStiffness
modifyTarget?
readonly modifyTarget?: (ideal) => number;Moves where the glide rests, called once with where it would: snapping a flick to a grid, say.
Parameters
ideal
number
Returns
number
Inherited from
power?
readonly power?: number;How far the glide carries, as a multiple of the velocity: it rests at initial + power × velocity. Default 0.8.
Inherited from
restDelta?
readonly restDelta?: number;The glide is done within this of where it rests, and the bounce within this of its edge. Default 0.5.
Inherited from
restSpeed?
readonly restSpeed?: number;The bounce rests below this speed, per second. Default 2.
Inherited from
timeConstant?
readonly timeConstant?: number;The glide's time constant, in seconds: it eases out as e^(−t / timeConstant). Default 0.325.
Inherited from
x?
readonly x?: InertiaEdges;y?
readonly y?: InertiaEdges;KeyframesOptions
keyframes' and keyframesValues' options: a tween's, its ease one easing or one per stretch
between stops (wrapping round when there are fewer, as Motion's), each stop's place in times, and
the repeats, over the whole run of stops.
Extends
Omit<TweenOptions,"ease">Modifiers
Properties
delay?
readonly delay?: number;Delay before the animation starts, in seconds. With animate's repeat / repeatType, or across
keyframes' stops, it holds once, before the first Interval: Machine.delay.
Inherited from
duration?
readonly duration?: number;Seconds it takes. Default 0.3.
Inherited from
ease?
readonly ease?:
| Definition
| readonly Definition[];repeat?
readonly repeat?: number;How many more times it plays after the first: a whole number, or Infinity for ever. Default 0.
Each starts the moment the one before ends, or repeatDelay after; delay holds once, before the
first.
Inherited from
repeatDelay?
readonly repeatDelay?: number;Seconds between plays, as Motion's repeatDelay. Default 0. Each play but the last holds where it
ended for this long; with an infinite repeat, every play does.
Inherited from
repeatType?
readonly repeatType?: "reverse" | "loop" | "mirror";How every other repeat runs, as Motion's repeatType. Default "loop".
"loop": each run starts atfromagain."reverse": every other run plays backwards in time, fromtotofromon the easing's curve reversed: aneaseOutrun comes back easing in."mirror": every other run plays fromtotofromon the same easing: aneaseOutrun comes back easing out.
Inherited from
reverse?
readonly reverse?: boolean;Plays it from to back to from; keyframes, through their stops from last to first. Default false.
Inherited from
times?
readonly times?: readonly number[];Each stop's place in the run, from 0 (its start) to 1 (its duration), in order, as Motion's
times: [0, 0.2, 1] reaches the second of three stops a fifth of the way in. Used when there's one
per stop; otherwise the stops are evenly spaced.
Machine
An animation as a value: what it does each frame, apart from what drives it. Build one with a
constructor or make, never as a literal: a literal, or a spread of a machine, isn't one.
Extends
PipeableInspectable
Type Parameters
F
F extends Frame<unknown>
Properties
~@wardic/core/Machine
readonly "~@wardic/core/Machine": object;_F
readonly _F: Covariant<F>;settles
readonly settles: boolean;Whether a run ends at its first settled Frame. chase doesn't: its Frame reports rest, but
the run goes on until it's removed. Nor does forever, whose Frames never settle.
span
readonly span: Span;The span each run gets, on either driver: its name and attributes, for traces and logs.
start
readonly start: () => (dt) => F;One run: a step from each tick's dt (seconds, as the Clock reports it) to that tick's
Frame. Each run holds its own state, so a machine can be started any number of times.
Returns
(dt) => F
Modifiers
How a tween repeats: repeat, repeatType and repeatDelay, and reverse.
Extended by
Properties
repeat?
readonly repeat?: number;How many more times it plays after the first: a whole number, or Infinity for ever. Default 0.
Each starts the moment the one before ends, or repeatDelay after; delay holds once, before the
first.
repeatDelay?
readonly repeatDelay?: number;Seconds between plays, as Motion's repeatDelay. Default 0. Each play but the last holds where it
ended for this long; with an infinite repeat, every play does.
repeatType?
readonly repeatType?: "reverse" | "loop" | "mirror";How every other repeat runs, as Motion's repeatType. Default "loop".
"loop": each run starts atfromagain."reverse": every other run plays backwards in time, fromtotofromon the easing's curve reversed: aneaseOutrun comes back easing in."mirror": every other run plays fromtotofromon the same easing: aneaseOutrun comes back easing out.
reverse?
readonly reverse?: boolean;Plays it from to back to from; keyframes, through their stops from last to first. Default false.
PointPhysics
A two-axis inertia's frame: its point, and each axis's velocity there.
Extends
Properties
done
readonly done: boolean;Whether it has settled: true on its last Frame.
Inherited from
value
readonly value: Point;The value this tick.
Inherited from
velocity
readonly velocity: Point;ResolvedTween
A tween's options with every default filled in.
Properties
delay
readonly delay: number;Seconds before it moves.
duration
readonly duration: number;The duration, at least Number.EPSILON, so a zero duration still divides.
ease
readonly ease: Easing;Its ease, resolved to the curve.
seconds
readonly seconds: number;The duration as given (0 for an instant tween): its span's, and what keyframes splits.
RunOptions
run's options: the token the run joins, so Supersede.end ends it with the others.
Properties
supersede
readonly supersede: Supersede;Span
A machine's span: a name and its attributes, opened by a driver once per run.
Properties
attributes
readonly attributes: Readonly<Record<string, unknown>>;name
readonly name: string;SpanOptions
withSpan's options, Effect's { attributes }.
Properties
attributes?
readonly attributes?: Readonly<Record<string, unknown>>;SpringOptions
A spring's options: its physics (stiffness, damping, mass) or its time (duration or
visualDuration, with bounce), where it starts and how fast, its rest thresholds, and a delay.
A bag is read once and kept by its identity: one changed after it's handed over isn't seen, so pass
a new one.
Extended by
Properties
bounce?
readonly bounce?: number;How much a spring set by time bounces: 0 none, toward 1 a lot. Default 0.3 with a duration, 0 with
a visualDuration; alone, it's a 0.8 s duration spring.
damping?
readonly damping?: number;How damped it is: higher settles sooner, with less overshoot. Default 26.
delay?
readonly delay?: number;Delay before the animation starts, in seconds.
duration?
readonly duration?: number;A spring set by time: it lands on its target at duration seconds, from rest, its stiffness and
damping solved from it and bounce. Within 0.01 to 10 s. A stiffness, damping or mass given
beside wins over it, and so does a visualDuration.
from?
readonly from?: number;Where it starts. Default 0.
mass?
readonly mass?: number;The mass it moves: heavier is slower. Default 1.
restDelta?
readonly restDelta?: number;At rest within this of its target. By default, as Motion's: 0.5 for a move of 5 or more, 0.005 for one shorter (an opacity, a scale, a nudge), by each value's distance each time its target changes.
restSpeed?
readonly restSpeed?: number;At rest below this speed, per second. By default, as Motion's: 2 for a move of 5 or more, 0.01 for one shorter.
stiffness?
readonly stiffness?: number;How stiff it is: higher is snappier. Default 170.
velocity?
readonly velocity?: number;The velocity it starts with, per second. Default 0.
visualDuration?
readonly visualDuration?: number;A spring set by time that has done most of its move by visualDuration seconds, and ends at rest
after, keeping the velocity it's handed. With bounce, or alone.
SpringValuesStart
springValues' run: each key's start and velocity, else the options'.
Properties
from?
readonly from?: Readonly<Record<string, number>>;velocity?
readonly velocity?: Readonly<Record<string, number>>;TweenOptions
A tween's options: its duration, ease and delay. A bag is read once and kept by its identity:
one changed after it's handed over isn't seen, so pass a new one.
Extended by
Properties
delay?
readonly delay?: number;Delay before the animation starts, in seconds. With animate's repeat / repeatType, or across
keyframes' stops, it holds once, before the first Interval: Machine.delay.
duration?
readonly duration?: number;Seconds it takes. Default 0.3.
ease?
readonly ease?: Definition;How it eases, as Motion's ease: one of Motion's names ("easeOut"), a cubic Bézier's four numbers
([0.25, 0.1, 0.35, 1]), or a function. Default linear.
Variables
CATCH_UP_DT
const CATCH_UP_DT: number;The step startAt catches up in: a 60 Hz frame.
clampDt
const clampDt: {
(max): <F>(self) => Machine<F>;
<F>(self, max): Machine<F>;
};self with each dt held to max before its step: for a machine built with make. The constructors hold theirs to MAX_DT.
Call Signature
(max): <F>(self) => Machine<F>;Parameters
max
number
Returns
<F>(self) => Machine<F>
Call Signature
<F>(self, max): Machine<F>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
max
number
Returns
Machine<F>
concat
const concat: {
<G>(that): <F>(self) => Machine<G | F>;
<F, G>(self, that): Machine<F | G>;
};that after self, on the frame after self settles: concatAll of the two. A self that never
settles never reaches that. Keeps self's span.
Call Signature
<G>(that): <F>(self) => Machine<G | F>;Type Parameters
G
G extends Frame<unknown>
Parameters
that
Machine<G>
Returns
<F>(self) => Machine<G | F>
Call Signature
<F, G>(self, that): Machine<F | G>;Type Parameters
F
F extends Frame<unknown>
G
G extends Frame<unknown>
Parameters
self
Machine<F>
that
Machine<G>
Returns
Machine<F | G>
Example
const trip = there.pipe(Machine.concat(back))delay
const delay: {
(seconds): <F>(self) => Machine<F>;
<F>(self, seconds): Machine<F>;
};A wait before self starts: for seconds, each frame is the frame self starts at; then self
steps on with the time left over. A negative seconds starts it that far in. delay(0) is self.
Keeps self's span.
Call Signature
(seconds): <F>(self) => Machine<F>;Parameters
seconds
number
Returns
<F>(self) => Machine<F>
Call Signature
<F>(self, seconds): Machine<F>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
seconds
number
Returns
Machine<F>
Example
const late = Machine.spring(1).pipe(Machine.delay(0.2))holdAfter
const holdAfter: {
(seconds): <F>(self) => Machine<F>;
<F>(self, seconds): Machine<F>;
};A wait after self settles: its settled frame for seconds more, then it settles. A self that
never settles, or a hold of 0 or less, is returned as it is. Keeps self's span.
Call Signature
(seconds): <F>(self) => Machine<F>;Parameters
seconds
number
Returns
<F>(self) => Machine<F>
Call Signature
<F>(self, seconds): Machine<F>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
seconds
number
Returns
Machine<F>
Example
const pause = Machine.tween(0, 1, { duration: 0.3 }).pipe(Machine.holdAfter(1))keyframesValues
const keyframesValues: (stops, options?) => Effect.Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>;A bag of values through each key's stops, as Motion's keyframes, each key blended as its Environment
blends it, as animateValues' are. One run drives every key: its duration, ease (one, or one per
stretch) and repeats are the bag's. Each key has its own stops, at their places in times when there's
one per stop, evenly spaced otherwise. A key with one stop holds it, and one with none is left out.
Building it needs the InterpolatorRegistry, once.
Parameters
stops
Readonly<Record<string, ReadonlyArray<number | string>>>
options?
Returns
Effect.Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>
map
const map: {
<F, G>(f): (self) => Machine<G>;
<F, G>(self, f): Machine<G>;
};self with each frame mapped by f. Keeps self's span.
Call Signature
<F, G>(f): (self) => Machine<G>;Type Parameters
F
F extends Frame<unknown>
G
G extends Frame<unknown>
Parameters
f
(frame) => G
Returns
(self) => Machine<G>
Call Signature
<F, G>(self, f): Machine<G>;Type Parameters
F
F extends Frame<unknown>
G
G extends Frame<unknown>
Parameters
self
Machine<F>
f
(frame) => G
Returns
Machine<G>
Example
const turn = Machine.spring(1).pipe(Machine.map((frame) => ({ ...frame, value: frame.value * 360 })))MAX_DT
const MAX_DT: 0.5 = 0.5;The most time a machine moves in one step: 0.5 s. A frame that took longer, such as the first after the app was hidden, moves it 0.5 s, and the animation plays the rest out from there, where Motion's jumps to its end. Every constructor holds each step to it.
MAX_DURATION
const MAX_DURATION: 20 = 20;How long durationOf lets a run go to settle: 20 s, as Motion's maxGeneratorDuration.
resolveTween
const resolveTween: (options) => ResolvedTween;A tween's options with its defaults filled in: 0.3 s, no delay, linear. A negative or non-finite
duration or delay, or an ease that's none of Motion's names, four numbers or a function, throws an
OptionError. For a tween you step yourself, as @wardic/dom's layout animations do. A bag is
resolved once and kept by its identity: one changed after it's handed over isn't seen, so pass a new one.
Parameters
options
Returns
run
const run: {
<F>(sink): (self) => Effect<F, never, FrameLoop>;
<F>(sink, options): (self) => Effect<F | typeof Superseded, never, FrameLoop>;
<F>(self, sink): Effect<F, never, FrameLoop>;
<F>(self, sink, options): Effect<F | typeof Superseded, never, FrameLoop>;
};Runs self on the Frame loop, from its next tick, handing each frame to sink. It succeeds with the
settled frame; one that never settles runs until it's interrupted, and interrupting removes it at
once. A frame handed to sink is the run's until the next tick: copy one to keep it. Given
{ supersede }, it ends with the other runs given the same token, succeeding with
Supersede.Superseded.
Call Signature
<F>(sink): (self) => Effect<F, never, FrameLoop>;Type Parameters
F
F extends Frame<unknown>
Parameters
sink
Sink<F>
Returns
(self) => Effect<F, never, FrameLoop>
Call Signature
<F>(sink, options): (self) => Effect<F | typeof Superseded, never, FrameLoop>;Type Parameters
F
F extends Frame<unknown>
Parameters
sink
Sink<F>
options
Returns
(self) => Effect<F | typeof Superseded, never, FrameLoop>
Call Signature
<F>(self, sink): Effect<F, never, FrameLoop>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
sink
Sink<F>
Returns
Effect<F, never, FrameLoop>
Call Signature
<F>(
self,
sink,
options
): Effect<F | typeof Superseded, never, FrameLoop>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
sink
Sink<F>
options
Returns
Effect<F | typeof Superseded, never, FrameLoop>
Example
const landed = yield* Machine.run(Machine.spring(200), (frame) => {
moveTo(frame.value)
})startAt
const startAt: {
(at): <F>(self) => Machine<F>;
<F>(self, at): Machine<F>;
};self started partway through: its first frame steps it from its start to at() seconds in, a 60 Hz
frame at a time, and every frame after steps as usual. at is read once a run, at its first frame. A
negative at() is a start still to come: it holds at its start that long. For an animation that
began before the app's code loaded, as a server-rendered one does, taken over where it has got to. Keeps self's span, and whether
it settles.
Call Signature
(at): <F>(self) => Machine<F>;Parameters
at
LazyArg<number>
Returns
<F>(self) => Machine<F>
Call Signature
<F>(self, at): Machine<F>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
at
LazyArg<number>
Returns
Machine<F>
Example
const resumed = Machine.tween(0, 1, { duration: 1 }).pipe(Machine.startAt(() => elapsedSeconds))withSpan
const withSpan: {
(name, options?): <F>(self) => Machine<F>;
<F>(self, name, options?): Machine<F>;
};self under the span name, with options.attributes, in place of its own: its runs' traces and
logs carry that name.
Call Signature
(name, options?): <F>(self) => Machine<F>;Parameters
name
string
options?
Returns
<F>(self) => Machine<F>
Call Signature
<F>(
self,
name,
options?
): Machine<F>;Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
name
string
options?
Returns
Machine<F>
Example
const bounce = Machine.spring(1).pipe(Machine.withSpan("app.bounce", { attributes: { card: id } }))Functions
animate()
function animate(
from,
to,
options?
): Machine<Frame<number>>;A tween that repeats: repeat plays it again, repeatType turns every other play ("reverse",
"mirror"), and reverse swaps its ends. delay holds once, before the first play, as Motion's
does, and repeatDelay after each play but the last, where it ended. Each play starts the moment the
one before ends; a finite repeat settles once the last ends, and repeat: Infinity never settles.
Parameters
from
number
to
number
options?
AnimateOptions = NO_OPTIONS
Returns
Example
const breathe = Machine.animate(1, 1.08, { duration: 1.2, ease: "easeInOut", repeat: Infinity, repeatType: "mirror" })animateValues()
function animateValues(
from,
to,
options?
): Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>;A bag of values tweened from from to to, each key blended as its Environment blends it: numbers,
unit strings, complex values, and its own kinds, such as @wardic/dom's colours. One tween drives every
key, so the repeats and delay apply to the whole bag. A pair that can't blend switches at the first
frame; the Environment can hold a key until the last, as @wardic/dom does a key that hides an element.
Building it needs the InterpolatorRegistry, once.
Parameters
from
Readonly<Values>
to
Readonly<Values>
options?
AnimateOptions = NO_OPTIONS
Returns
Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>
Example
const fade = yield* Machine.animateValues({ opacity: 0, color: "#bf616a" }, { opacity: 1, color: "#a3be8c" }, { duration: 0.3 })chase()
function chase(getTarget, options?): Machine<Physics>;A spring that follows a moving target: getTarget() is read every step, so it tracks a cursor, a
scroll position or a target that changes often. Its frames report rest, but it never settles: a run
ends only when it's removed.
Parameters
getTarget
() => number
options?
SpringOptions = NO_OPTIONS
Returns
Example
const follow = Machine.chase(() => pointer.x, Spring.gentle)concatAll()
function concatAll<F>(intervals): Machine<F>;Machines played one after another, as one run: each starts on the frame after the one before it
settles, so a long sequence runs up to a frame a seam behind wall time. For tweens back to back,
exactly on time, use keyframes. A machine that never settles, a chase or a forever, is the last
one reached. One machine is returned as it is. Keeps the first's span.
Type Parameters
F
F extends Frame<unknown>
Parameters
intervals
readonly [Machine<F>, Machine<F>]
Returns
Machine<F>
Example
const there = Machine.tween(0, 100, { duration: 0.3 })
const back = Machine.tween(100, 0, { duration: 0.3 })
const trip = Machine.concatAll([there, back])decay()
function decay(
initial,
velocity,
options?
): Machine<Physics>;A decay: from initial at velocity, slowing by friction, to rest velocity / friction away,
whatever the frame rate.
Parameters
initial
number
velocity
number
options?
DecayOptions = NO_OPTIONS
Returns
Example
const coast = Machine.decay(x, 900, { friction: 4 })decayVec()
function decayVec(
initial,
velocity,
options
): Machine<Frame<Point>>;A decay on two axes together: a point each frame, settling once both rest.
Parameters
initial
velocity
options
Returns
durationOf()
function durationOf<F>(self): number;How long a run of self takes to settle, in seconds: Infinity for one that doesn't, a chase or a
forever, or hasn't by MAX_DURATION. It runs the machine to find out, up to 1,200 steps a call.
Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
Returns
number
Example
Machine.durationOf(Machine.spring(1, Spring.gentle)) // ≈ 1.1forever()
function forever<F>(self): Machine<F>;self started again each time it settles, for ever, so a run never settles. Each restart is up to a
frame behind wall time; animate's repeat: Infinity is exact. A self that never settles is
returned as it is. Keeps self's span.
Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
Returns
Machine<F>
inertia()
function inertia(
initial,
velocity,
options?
): Machine<Physics>;An inertia: a glide from initial at velocity toward initial + power × velocity, or where
modifyTarget moves that, easing out over timeConstant; where it would pass min or max, or
starts past one, it springs back to that edge. What a drag's release runs.
Parameters
initial
number
velocity
number
options?
InertiaOptions = NO_OPTIONS
Returns
Example
// A flick that rests on a 100 px grid, within 0 and 800.
const snap = Machine.inertia(x, velocity, { modifyTarget: (end) => Math.round(end / 100) * 100, min: 0, max: 800 })inertiaValues()
function inertiaValues(
from,
options?,
start?
): Machine<MultiPhysics>;Inertia on a bag of numbers, as a transition's type: "inertia": one glide per key from from, at
its velocity in start.velocity (else options.velocity, else 0), on the shared options, after
options.delay, settling once every key rests. It takes no target: each key rests where its glide
does, through modifyTarget, held within min and max. With no velocity, a key rests where it
starts.
Each frame carries a per-key velocity beside value, and is rewritten every tick: copy a frame to
keep it.
Parameters
from
Readonly<Record<string, number>>
options?
InertiaValuesOptions = NO_OPTIONS
start?
InertiaValuesStart = NO_START
Returns
inertiaVec()
function inertiaVec(
initial,
velocity,
options?
): Machine<PointPhysics>;Inertia on two axes together: a point each frame, each axis with its own edges, settling once both rest. What a drag's release runs; an animation that takes the release over starts from its velocity.
Parameters
initial
velocity
options?
InertiaVecOptions = NO_OPTIONS
Returns
isMachine()
function isMachine(u): u is Machine<Frame<unknown>>;Whether u is a machine (built by make or a constructor).
Parameters
u
unknown
Returns
u is Machine<Frame<unknown>>
keyframes()
function keyframes(stops, options?): Machine<Frame<number>>;A tween through a list of stops, as Motion's keyframes: each stretch between two stops eased whole by
ease (one, or one per stretch, wrapping round), each stop at its place in times (evenly spaced
without one per stop). The repeats run the whole list: repeat plays it again, "reverse" plays
every other pass backwards, "mirror" every other pass through the stops from last to first, and
reverse every pass so. One stop, or none, holds still. delay holds once, before the first.
Parameters
stops
readonly number[]
options?
KeyframesOptions = NO_OPTIONS
Returns
Example
const shake = Machine.keyframes([0, -12, 12, -6, 6, 0], { duration: 0.5 })make()
function make<F>(fields): Machine<F>;A machine from its fields: a run's start, whether it settles, and its span. For a motion of your
own; the constructors cover the common ones.
Type Parameters
F
F extends Frame<unknown>
Parameters
fields
settles
boolean
span
start
() => (dt) => F
Returns
Machine<F>
Example
// A blink: 1 and 0 by turns, twice a second, for ever.
const blink = Machine.make({
settles: false,
span: { name: "app.blink", attributes: {} },
start: () => {
let time = 0
return (dt) => {
time += dt
return { value: Math.floor(time * 2) % 2, done: false }
}
},
})spring()
function spring(target, options?): Machine<Physics>;A spring toward target, from options.from (0 by default), settling at rest. A moving target is
chase's.
Parameters
target
number
options?
SpringOptions = NO_OPTIONS
Returns
Example
const pop = Machine.spring(1, { from: 0.8, stiffness: 400, damping: 15 })springBlend()
function springBlend(
from,
to,
options?
): Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>;A bag of values blended from from to to by one spring's progress: the spring runs from rest on a
0 to 100 progress, and each key is blended at progress / 100. It's how a spring moves values that
aren't numbers, a colour or a unit string, as Motion's spring does.
- The progress spans 0 to 100, as a number going 100 would, so
restDeltaandrestSpeedmean the same for both, and a string key beside anxgoing 0 to 100 lands with it. - It starts from rest:
options.fromandoptions.velocitydon't move it. - Past 1, a key does what its blend does past 1: a number or a unit string overshoots, and
@wardic/dom's colour holds at its target. A pair that can't blend switches at its first frame.
Parameters
from
Readonly<Values>
to
Readonly<Values>
options?
SpringOptions = NO_OPTIONS
Returns
Effect<Machine<Frame<Values>>, never, InterpolatorRegistry>
springValues()
function springValues(
target,
options?,
start?
): Machine<MultiPhysics>;A bag of numbers sprung toward target: one spring per key on the shared options, from start's
from and velocity (else options.from and options.velocity, else 0), settling once every key
rests.
Each frame carries a per-key velocity beside value; a settled key reports 0. Seeding from and
velocity from a frame of the run before keeps its velocity when the target changes. Each frame is
rewritten every tick: copy one, or its records, to keep it; the settled frame is stable.
Parameters
target
Readonly<Record<string, number>>
options?
SpringOptions = NO_OPTIONS
start?
SpringValuesStart = NO_START
Returns
Example
const card = Machine.springValues({ x: 120, y: 40, scale: 1.1 }, Spring.stiff, { from: { x: 0, y: 0, scale: 1 } })toStream()
function toStream<F>(self): Stream<F, never, Clock>;self as a Stream over the Clock's ticks: a frame a tick, through its settled frame when it settles.
Each subscriber gets a run of its own, and each frame is its to keep. For one value in an Effect
program; run steps every running machine in one pass a frame, which is cheaper for many.
Type Parameters
F
F extends Frame<unknown>
Parameters
self
Machine<F>
Returns
Stream<F, never, Clock>
Example
yield* Machine.toStream(fadeIn).pipe(Stream.runForEach((frame) => Effect.sync(() => draw(frame.value))))tween()
function tween(
from,
to,
options
): Machine<Frame<number>>;A tween from from to to over options.duration, eased by its ease, after its delay.
Parameters
from
number
to
number
options
Returns
Example
const slide = Machine.tween(0, 240, { duration: 0.4, ease: "easeInOut" })