Interpolator
The kinds of value Wardic blends: numbers, arrays of numbers, numbers with units ("10px"), and
complex values, strings with numbers among other text, as a shadow's or a path's. Each is an
Entry: how an endpoint of its kind is read, written, and blended with another. An Environment
registers these in its InterpolatorRegistry beside its own kinds, as @wardic/dom adds its colours, and
you can register yours.
import * as Interpolator from "@wardic/core/Interpolator"
// A kind of your own: angles in turns, `"0.25turn"`.
const turns: Interpolator.Entry<number, string> = {
name: "turns",
parse: (value) => (typeof value === "string" && value.endsWith("turn") ? Option.some(parseFloat(value)) : Option.none()),
format: (amount) => `${amount}turn`,
blend: (from, to) => Option.some((t) => `${from + (to - from) * t}turn`),
}Its exports also name types the module doesn't export: its internal types.
Interfaces
Complex
A complex value, read: the text around its tokens, and the tokens, numbers and its Environment's
kinds, in order. parts.length === tokens.length + 1.
Properties
parts
readonly parts: readonly string[];tokens
readonly tokens: readonly ComplexToken[];ComplexOptions
The spans and kinds of token an Environment names in its complex values.
Properties
text?
readonly text?: readonly RegExp[];Patterns for spans that are only text: matched whole, before tokens and numbers, so the digits in
them are never numbers; kept as text; and counted when two values match. No capturing groups. None
by default: core names no Environment's syntax, and @wardic/dom's are its own.
tokens?
readonly tokens?: readonly TokenKind<any>[];Kinds of token besides numbers: each a pattern, and the Interpolator its tokens are read, blended
and written through. Two values blend with the same count of each kind, the n-th token of a kind
with the n-th of that kind. None by default: @wardic/dom's colours are its own.
Entry
A kind of value the registry can blend: how an endpoint of it is read and written, and how two of it blend.
parsereads an endpoint of the kind, any value at all:Someof what it read,Nonefor a value of another kind, its type checked first. An endpoint it reads is this kind's, and one it rejects isn't: reading is matching. The registry parses once, when an animation is built, never per frame.formatwrites a read value back: what each frame writes with.blendtakes two read endpoints, once, and returns the function each frame calls with its progresst, which blends and writes. Work on the pair, comparing two structures or settling a unit, happens here, once.Nonewhen the pair can't blend: a Discrete pair, which the registry switches at the first frame, with a warning.
The built-in kinds (a number, an array, a unit string, a complex value) are registered as an
Environment is set up, beside its own, as @wardic/dom's colours, and yours can be too.
Type Parameters
Decoded
Decoded
Encoded
Encoded
Properties
blend
readonly blend: (from, to) => Option<(t) => Encoded>;Two read endpoints' blend: the closure the frame calls with t, or None. Pure, and so is the
closure: a blend is kept and shared, so one pair's closure serves every element animating it, and
state kept between calls would leak from one to the next.
Parameters
from
Decoded
to
Decoded
Returns
Option<(t) => Encoded>
format
readonly format: (value) => Encoded;Writes a read value back.
Parameters
value
Decoded
Returns
Encoded
name
readonly name: string;Unique name for the value kind, e.g. "number", "unit".
parse
readonly parse: (value) => Option<Decoded>;Reads an endpoint of the kind: Some of it read, or None for any other value.
Parameters
value
unknown
Returns
Option<Decoded>
KindToken
A token of one of an Environment's kinds, read: its kind, its Interpolator's name, and the value that Interpolator read.
Properties
kind
readonly kind: string;value
readonly value: unknown;TokenKind
A kind of token an Environment names in its complex values besides numbers: what one looks like, and
the Interpolator that reads, blends and writes it, usually the one it registers for a value of that
kind on its own, as @wardic/dom's colours. Its tokens are told apart by that Interpolator's name.
Type Parameters
Decoded
Decoded = any
Properties
entry
readonly entry: Entry<Decoded, string>;How a token of the kind reads (parse), blends and writes (format).
pattern
readonly pattern: RegExp;What a token of the kind looks like: matched case-insensitively, after the text spans and before numbers. No capturing groups: the parse splits a string around its tokens.
Type Aliases
ComplexToken
type ComplexToken = number | KindToken;A complex value's token, read: a number, or a token of one of its Environment's kinds.
Variables
array
const array: Entry<ReadonlyArray<number>, ReadonlyArray<number>>;Interpolates fixed-length numeric arrays element-wise (e.g. RGB tuples): it reads an array of numbers as it is.
complex
const complex: Entry<Complex, string>;The complex value kind with no text spans and no kinds of token: core's own (see complexWith).
defaults
const defaults: ReadonlyArray<Entry<any, any>>;The kinds core ships, in the order a pair is tried: number and array first, unit before
complex, so "10px" is a unit, and complex last, for the strings the others didn't take. An
Environment adds its own among them, as @wardic/dom's colours before unit.
number
const number: Entry<number, number>;Interpolates plain numbers: it reads any number as it is, NaN and the infinities too.
unit
const unit: Entry<ParsedUnit, string | number>;A number with a unit, "10px" to "20px", "0%" to "100%", or a bare number paired with one, 0
to "10px": the unit is taken from whichever endpoint has one, and each frame blends the number and
writes it with the unit. unit.parse reads a string or a number (" 10px " is { value: 10, unit: "px" }, 120 is { value: 120, unit: "" }), and unit.format writes one back ("10px").
Two different units, both present ("10px", "1em"), can't blend: a Discrete pair, switched at the
first frame, with a warning.
Functions
complexWith()
function complexWith(options): Entry<Complex, string>;The complex value kind, for an Environment's text spans and kinds of token: a string with numbers or
tokens among other text, as a path's, a shadow's or a gradient's, blended token by token, as Motion's
mixComplex. Two blend when they hold the same count of each kind and the
start has at least as many numbers as the target: the n-th number with the n-th, and the n-th token
of a kind with the n-th of it, written in the target's text: a shadow with a colour and three
lengths blends into another with a colour and three lengths, wherever each writes its colour. Any
other two can't: a Discrete pair, switched to the target at the first frame, with a warning.
Two paths with the same commands morph; paths with different commands don't. Register it last, so
the specific kinds win: "10px" is a unit, and a lone colour @wardic/dom's colour kind. As Motion's,
an arc command's flags are blended as numbers, so an arc path can pass through invalid flags.
Its parse reads a string into its parts and tokens, and its format writes them back, numbers in
JavaScript's shortest form, so "M0.50,1e3" writes back as "M0.5,1000".
Parameters
options
Returns
Example
// An Environment's colours as a kind of token among the numbers, as `@wardic/dom`'s are:
const complex = Interpolator.complexWith({ tokens: [{ pattern: colorPattern, entry: colorEntry }] })unitOf()
function unitOf(value): Option<string>;The unit of a number-with-unit string, as the unit kind reads it ("" for a bare number), or None
for another string ("auto", "M0,0 L1,1"). Two strings whose units differ, both present, can't blend.
Parameters
value
string
Returns
Option<string>