Generated from the public headers, which are the source of truth: 125 functions across 13 headers.
base.hclip.hcontext.heasing.hevent.hinterpolate.hpath.hplayer.hsample.hspring.htarget.htiming.htransition.hbase.hThe base of the Maul Tween API: the library version, the export and attribute macros, the result codes every fallible function returns, the allocator a context takes, and the four-channel values and their kinds that targets and tracks hold.
mtwnVersion mtwnGetVersion(void);
Returns the version of the library that was linked, which may differ from the MTWN_VERSION macros a program was compiled with.
Returns: The library version.
Thread safety. Safe from any thread.
const char* mtwnGetResultName(mtwnResult result);
Returns the name of a result code, for diagnostics.
Parameters:
result: Any value; an unknown one is named as such.Returns: A static, NUL-terminated string such as "mtwn_errorCapacity".
Thread safety. Safe from any thread.
clip.hClips: immutable descriptions of tracks on nested timelines with labels and marks, built node by node at positions resolved when added, then sealed. A sealed clip is read through the values layer from any thread while it lives, and plays on any set of targets, its tracks addressing slots.
static inline mtwnClipDef mtwnDefaultClipDef(void);
Makes a clip def for a small clip: 16 nodes, 32 keyframes, 8 slots, 64 points of linear(), about 15 KB of clip storage (mtwnContext_GetClipBytes says how much).
Returns: The def.
Thread safety. Safe from any thread.
static inline mtwnClipTrackDef mtwnDefaultClipTrackDef(void);
Makes a clip track def: on the root at time 0, slot 0, a scalar track (mtwnDefaultTrackDef), Web Animations' default timing with a duration of 1 second, no keyframes.
Returns: The def.
Thread safety. Safe from any thread.
static inline mtwnClipTimelineDef mtwnDefaultClipTimelineDef(void);
Makes a clip timeline def: on the root at time 0, lasting to its latest child's end, Web Animations' default timing.
Returns: The def.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_GetClipBytes(const mtwnContext* context, const mtwnClipDef* def, uint64_t* bytesOut);
Gives the clip storage a clip of a def takes, so a host can grow its context's clipStorageBytes (mtwnContext_Grow) for the clips it makes. It takes the context so that the def is read only by a library whose ABI the context's def has matched.
Parameters:
context: The context.def: The clip's def.bytesOut: Receives the bytes; 0 on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument or a def without its cookie; mtwn_errorLimit for a capacity past MTWN_MAX_COUNT.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnCreateClip(mtwnContext* context, const mtwnClipDef* def, mtwnClipId* clipOut);
Makes a clip: allocates its storage in one block, counted against the context's clip storage. Its root timeline, node 1, lasts as long as its latest child.
Parameters:
context: The context.def: The def.clipOut: Receives the clip's id, or the null id on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument or a def without its cookie; mtwn_errorLimit for a capacity past MTWN_MAX_COUNT; mtwn_errorCapacity when the context holds its capacity of clips, the storage would pass its clip storage, or the allocator fails.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnDestroyClip(mtwnContext* context, mtwnClipId clip);
Destroys a clip and frees its storage.
Parameters:
context: The context.clip: The clip.Returns: mtwn_success; mtwn_errorInvalid for a null context; mtwn_errorStale for an id that names no live clip; mtwn_errorBusy while a player plays it, not counted as misuse: a player not kept frees itself at an end the update decides.
Thread safety. Safe from any thread; the context is used by one thread at a time.
bool mtwnClip_IsValid(const mtwnContext* context, mtwnClipId clip);
Tells whether an id names a live clip. Not counted as misuse.
Parameters:
context: The context, or NULL.clip: The id.Returns: Whether the clip is alive.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_AddTrack(mtwnContext* context, mtwnClipId clip, const mtwnClipTrackDef* def, mtwnNode* nodeOut);
Adds a track: copies its keyframes into the clip, makes the track there (mtwnMakeTrack, with the lengths and mixes in the clip) and resolves its position to a start time.
Parameters:
context: The context.clip: The clip, not sealed.def: The def: a timeline of the clip as parent, a known position kind and a finite offset, a slot below the slot capacity and of the same kind as its other tracks, a timing mtwnValidateTiming accepts, and a track and keyframes mtwnMakeTrack accepts.nodeOut: Receives the node, or 0 on failure. Set to 0 before the def is read, so given the def's own parent it makes that parent 0, which is refused.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a def without its cookie or outside the above; mtwn_errorStale for a clip that is not alive; mtwn_errorState for a sealed clip; mtwn_errorCapacity when the clip holds its capacity of nodes, keyframes or points; mtwn_errorLimit for a node whose end would take its clip's finite end past MTWN_SEEK_LIMIT. The linear() points of its timing's and keyframes' easings are copied into the clip, so the host's may change or go once added; points the host changed from the order their maker left them in (not finite, or an input below one before it) are mtwn_errorInvalid.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_AddTimeline(mtwnContext* context, mtwnClipId clip, const mtwnClipTimelineDef* def, mtwnNode* nodeOut);
Adds a timeline: a group of children taking its transformed time. Its end in its parent follows its children as they arrive when its duration is theirs; children already placed after it keep their starts.
Parameters:
context: The context.clip: The clip, not sealed.def: The def: a timeline of the clip as parent, a position as for tracks, a timing mtwnValidateTiming accepts with a monotonic easing (mtwnIsEasingMonotonic).nodeOut: Receives the node, or 0 on failure. Set to 0 before the def is read, so given the def's own parent it makes that parent 0, which is refused.Returns: As mtwnClip_AddTrack; mtwn_errorLimit also for a timeline past MTWN_MAX_CLIP_DEPTH.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_AddLabel(mtwnContext* context, mtwnClipId clip, mtwnNode parent, mtwnPosition position, uint32_t key, mtwnNode* nodeOut);
Adds a label: a time in its parent named by a host key, unique in the parent, for positions and seeking. It is not a previous child and does not lengthen its parent.
Parameters:
context: The context.clip: The clip, not sealed.parent: A timeline of the clip.position: Where, as for tracks.key: The host's key.nodeOut: Receives the node, or 0 on failure.Returns: As mtwnClip_AddTrack; mtwn_errorInvalid also for a key the parent already has.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_AddMark(mtwnContext* context, mtwnClipId clip, mtwnNode parent, mtwnPosition position, uint32_t key, mtwnNode* nodeOut);
Adds a mark: an instant in its parent that gives an event, with the host's key, each time playback crosses it. It is not a previous child and does not lengthen its parent.
Parameters:
context: The context.clip: The clip, not sealed.parent: A timeline of the clip.position: Where, as for tracks.key: The host's key; marks may share one.nodeOut: Receives the node, or 0 on failure.Returns: As mtwnClip_AddTrack.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_Seal(mtwnContext* context, mtwnClipId clip);
Seals a clip: it can be read and played, and no longer changed.
Parameters:
context: The context.clip: The clip.Returns: mtwn_success; mtwn_errorInvalid for a null context; mtwn_errorStale for a clip that is not alive; mtwn_errorState for a clip already sealed.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_GetTrack(const mtwnContext* context, mtwnClipId clip, mtwnNode node, mtwnClipTrack* trackOut);
Reads a sealed clip's track node.
Parameters:
context: The context.clip: The clip.node: A track node of the clip.trackOut: Receives the track, its timing, start, parent and slot; sample it with mtwnComputeTiming and mtwnSampleTrack from any thread while the clip lives (its easings' linear() points are the clip's copies); zero on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument or a node that is not a track of the clip; mtwn_errorStale for a clip that is not alive; mtwn_errorState for one not sealed.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_GetNode(const mtwnContext* context, mtwnClipId clip, mtwnNode node, mtwnClipNodeInfo* infoOut);
Reads any node of a sealed clip.
Parameters:
context: The context.clip: The clip.node: A node of the clip, the root included.infoOut: Receives what the node is; zero on failure.Returns: As mtwnClip_GetTrack, for any node.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_FindLabel(const mtwnContext* context, mtwnClipId clip, mtwnNode parent, uint32_t key, double* secondsOut);
Finds a label of a sealed clip by its parent and key.
Parameters:
context: The context.clip: The clip.parent: The timeline the label is in.key: The label's key.secondsOut: Receives its time in the parent; 0 on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a parent that is not a timeline of the clip, or no such label; mtwn_errorStale and mtwn_errorState as mtwnClip_GetTrack.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClip_GetDuration(const mtwnContext* context, mtwnClipId clip, double* secondsOut);
Reads a sealed clip's duration: its root's end.
Parameters:
context: The context.clip: The clip.secondsOut: Receives the duration; 0 on failure.Returns: As mtwnClip_GetTrack, without the node.
Thread safety. Safe from any thread; the context is used by one thread at a time.
context.hThe context: the owner of targets, clips and players, made from a def that names every capacity and allocated in one block through the host's allocator. Nothing allocates after creation. The host's code a context's functions run (a host easing, the allocator, the task system's functions and tasks) calls no function of that context: while one runs, those taking the context non-const refuse with mtwn_errorBusy and count one misuse, and the const ones read it in the middle of a call. Two exceptions refuse as the others do: mtwnTarget_GetState, whose velocity may run a host easing again; and, while an update's clip players run in groups on the task system, the readers of targets and players (mtwnTarget_GetValue, mtwnContext_ReadTargets, mtwnClipPlayer_GetState and mtwnContext_MeasureTransition), which a group may be writing.
static inline mtwnContextDef mtwnDefaultContextDef(void);
Makes a context def for a medium host: 1024 targets, 256 players with 64 points of linear() for each transition, 16 clips, 256 events, 1024 bindings, sharing for clips of up to 128 nodes and 64 records, and 240 KiB of clip storage, which holds 16 clips of the default clip def, the C library's allocator and no task system. Built in the program, so it carries the version of the headers the program includes.
Returns: The def.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnCreateContext(const mtwnContextDef* def, mtwnContext** contextOut);
Makes a context: checks the def and allocates everything the context holds in one block.
Parameters:
def: The def.contextOut: Receives the context, or NULL on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument or a def without its cookie; then mtwn_errorVersion for a def stamped by headers of another ABI version than the library's, before anything else in it is read; mtwn_errorInvalid for an allocator or a task system with one function of the two; mtwn_errorLimit for a capacity past MTWN_MAX_COUNT or clip storage past MTWN_MAX_CLIP_STORAGE; mtwn_errorCapacity when the allocator fails or the block's size does not fit.
Thread safety. Safe from any thread.
void mtwnDestroyContext(mtwnContext* context);
Destroys a context and everything it holds.
Parameters:
context: The context, or NULL.Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_Grow(mtwnContext** contextInOut, const mtwnContextDef* def);
Grows a context to a def's capacities, each at least the context's own but the sharing's, which may be any, and takes the def's task system, with the allocator it was made with: the one time after its creation it allocates, and only when asked (it never grows by itself). Its objects move to one new block, their ids unchanged, and the old block is freed, so the context's address changes: the call writes the new one. On any failure nothing changes.
Parameters:
contextInOut: The context; receives the grown one.def: The capacities: start from the context's own.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a def without its cookie, a capacity below the context's, another allocator, or a task system with one function of the two; mtwn_errorLimit for a capacity past its maximum, as mtwnCreateContext; mtwn_errorVersion for a def of another ABI version; mtwn_errorCapacity when the allocator fails or the block's size does not fit.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint64_t mtwnContext_GetMisuse(const mtwnContext* context);
Returns how many calls against the context were refused for an invalid argument, a stale target or clip id, a call the object's state does not allow (mtwn_errorState) or a call back in from the host's code since it was made, and the samples of its updates that met a host easing's NaN: one for a transition's value at an update, one for each player's clip track at an update, whichever of the track's easings gave it; the earlier sample a velocity is measured from counts none. A full capacity, the stale id of a player the context handed out, kept or not, and a clip a player still holds count none: each depends on state the library changes. A player id never handed out, the null id among them, counts.
Parameters:
context: The context, or NULL.Returns: The count; 0 for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint64_t mtwnContext_GetSerialAdvanceCount(const mtwnContext* context);
Returns how many clip players' advances a context with a task system ran on the calling thread since it was made: a player whose clip has more than 128 nodes and is played by other players too, one whose targets of its own might not fit its group's staging, one whose staging ran out, and those after it in its group. A count that grows asks for larger binding or event capacities, or smaller clips.
Parameters:
context: The context, or NULL.Returns: The count; 0 without a task system or a context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint64_t mtwnContext_GetMemoryBytes(const mtwnContext* context);
Returns the size of the block the context holds everything in.
Parameters:
context: The context, or NULL.Returns: Bytes; 0 for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
void mtwnContext_EnableReducedMotion(mtwnContext* context, bool enabled);
Turns reduced motion on or off; it is off when a context is made. While it is on, every transition and every running clip's player with a finite end finishes at the next update, its delay skipped and its events at that update's time, unless its def marks it essential; a player with an infinite end plays on, the host's to keep, seek or stop. Turning it off reaches what has not finished. The host reads the platform's preference and turns it on or off. Its only refusals are misuse, so it returns nothing: a null context changes nothing, and a call back in from the host's code the context runs changes nothing and counts one misuse.
Parameters:
context: The context, or NULL.enabled: Whether motion is reduced.Thread safety. Safe from any thread; the context is used by one thread at a time.
bool mtwnContext_IsReducedMotionEnabled(const mtwnContext* context);
Returns whether reduced motion is on.
Parameters:
context: The context, or NULL.Returns: Whether it is; false for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint32_t mtwnContext_GetPlayingOnCount(const mtwnContext* context);
Returns how many clips' players the last update left running under reduced motion though not essential: those that could not finish, their end infinite or their rate 0. When it is not 0, the host finds them by mtwnClipPlayer_GetState's playsOnReduced and keeps, seeks or stops each.
Parameters:
context: The context, or NULL.Returns: The count; 0 for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_Update(mtwnContext* context, uint64_t timeNs, mtwnTargetId* changedOut, uint32_t changedCapacity, uint32_t* changedTotalOut);
Advances every player to the host's time, in the order they were made, later ones writing over earlier ones: transitions sample their curves, write their targets and end; clips' players sample their clips into their bound targets, and those that finish, unless kept, commit what they fill forward as their targets' bases and are freed. A target bound to a clip's player that no player writes shows its base. Reports the targets whose value or base changed since the last report, in the order they changed; a target appears once.
Parameters:
context: The context.timeNs: The host's time in nanoseconds, never less than the last update's.changedOut: Receives the first changedCapacity changed targets; NULL only with a capacity of 0. On failure its first changedCapacity entries, up to the context's target capacity, are the null id; a null context, or a call back in from the context's own host code (mtwn_errorBusy), leaves it as it was.changedCapacity: Its length.changedTotalOut: Receives how many targets changed, which may exceed the capacity; those past it are left out of the report only. May be NULL; 0 on failure but a call back in (mtwn_errorBusy), which leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null context, a null array with a capacity, or a time before the last update's, nothing advanced.
Thread safety. Safe from any thread; the context is used by one thread at a time.
easing.hEasing: curves that map a timing's progress to eased progress. An easing is a value made by a function that validates it and sampled by mtwnSampleEasing: Penner's families, which land exactly on 0 and 1, and CSS Easing Level 2 entire. Every kind has the same four modes.
mtwnEasing mtwnMakeLinearEasing(void);
Makes the linear easing, whose eased progress is its progress.
Returns: The easing.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakePowerEasing(mtwnEaseMode mode, double exponent, mtwnEasing* easingOut);
Makes the power easing p^k: quad for k = 2, cubic 3, quart 4, quint 5. GSAP's power(n) is k = n + 1. Integer exponents up to 8 are computed by multiplication.
Parameters:
mode: The mode.exponent: k, finite and above 0.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown mode or an exponent outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakePennerEasing(mtwnEasingKind kind, mtwnEaseMode mode, mtwnEasing* easingOut);
Makes one of Penner's easings without parameters: sine, expo, circ or bounce. Each lands exactly on 0 at 0 and on 1 at 1; expo is normalized to do so and differs from Penner's by at most 2^-10. GSAP 3's expo is not Penner's but a blend of its own, 2^(10 (p - 1)) p + p^6 (1 - p), up to 2^-7 from this one.
Parameters:
kind: mtwn_easingSine, mtwn_easingExpo, mtwn_easingCirc or mtwn_easingBounce.mode: The mode.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, another kind or an unknown mode.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeBackEasing(mtwnEaseMode mode, double overshoot, mtwnEasing* easingOut);
Makes the back easing p^2 ((s + 1) p - s), normalized to land on 1. GSAP's back(s) and Penner's in and out use s as given, 1.70158 by default; Penner's and tween.js's in-out use 1.525 s, which is this easing with that s.
Parameters:
mode: The mode.overshoot: s, finite and at least 0; 0 is the cubic.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown mode or an overshoot outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeElasticEasing(mtwnEaseMode mode, double amplitude, double period, mtwnEasing* easingOut);
Makes the elastic easing, GSAP's elastic(amplitude, period): out is 1 + a 2^(-10 p) sin((p - c) 2 pi / P) with c = P asin(1 / a) / (2 pi), normalized to land on 0 and 1, and in its reflection. An amplitude below 1 is 1 with the period divided by it, as GSAP does. GSAP's defaults are amplitude 1 with period 0.3, or 0.45 in-out; Penner's and tween.js's are amplitude 1, period 0.4. GSAP and tween.js miss 1 at the end by up to q 2^-10, q the larger of a and 1, and set it there, so they differ from this by at most q (1 + q) 2^-10 / (1 - q 2^-10).
The curve ends at 1 + a 2^-10 sin(...) before it is normalized by it, which an amplitude up to 512 keeps from 1/2 to 3/2. A period, once an amplitude below 1 has stretched it, below 2^-10 is refused: a fit of MTWN_MAX_FIT_POINTS points has 64 points to each oscillation there, which trace a sine to about 0.1% of its height, and finer ones it cannot follow.
Parameters:
mode: The mode.amplitude: a, above 0 and at most 512.period: P, finite, in units of progress; P, or P / a for an amplitude below 1, at least 2^-10.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown mode or a parameter outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeHostEasing(mtwnEaseMode mode, mtwnEaseFunction* function, void* context, mtwnEasing* easingOut);
Makes an easing of a host function, called with progress clamped to 0 to 1, under the mode's reflections. The library neither checks nor forces its ends. A NaN breaks the function's contract: the library takes the progress the function was called with in its place, the curve linear there in every mode, and a context counts one misuse for each sample of an update that met one: a transition's value, and a clip track's for each player (mtwnContext_GetMisuse). Its infinity is kept: a transition or track between equal ends stays at them, and one between others is held at the largest finite float wherever a float is written.
Parameters:
mode: The mode.function: The function; it must be safe to call from every thread that samples the easing, and calls no function of a context sampling it.context: Passed to the function; may be NULL.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null function or easingOut or an unknown mode.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeCubicBezierEasing(double x1, double y1, double x2, double y2, mtwnEasing* easingOut);
Makes CSS's cubic-bezier(x1, y1, x2, y2), solved by safeguarded Newton to |x(t) - x| <= 1e-14: exactly 0 at 0 and 1 at 1, and outside 0 to 1 extended along CSS's end tangents.
Parameters:
x1: The first control point's x, from 0 to 1.y1: Its y, at most 2^1000 in magnitude, which keeps the curve's polynomial finite.x2: The second control point's x, from 0 to 1.y2: Its y, likewise.easingOut: Receives the easing, in mode mtwn_easeIn; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a point outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeStepsEasing(uint32_t count, mtwnStepPosition position, mtwnEasing* easingOut);
Makes CSS's steps(count, position), with CSS's before flag: in the before phase, a progress landing exactly on a step takes the step below.
Parameters:
count: The steps: at least 1, or 2 for mtwn_jumpNone.position: Where it jumps.easingOut: Receives the easing, in mode mtwn_easeIn; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown position or a count outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeCssEasing(mtwnCssKeyword keyword, mtwnEasing* easingOut);
Makes the easing a CSS keyword names.
Parameters:
keyword: The keyword.easingOut: Receives the easing, in mode mtwn_easeIn; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or an unknown keyword.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeLinearPointsEasing(mtwnLinearPoint* points, uint32_t count, mtwnEasing* easingOut);
Makes CSS's linear() from its points, canonicalizing them in place as CSS does: a first input not given is 0 and a last one 1 or the largest before it; an input below an earlier one is raised to it; runs not given are spread evenly between their neighbors. The easing references the points, which must outlive it and should not change: changed, even out of order, while finite they give an unspecified finite value. Outside the points' inputs it extends their end segments, a value past the doubles' range given as the largest finite double of its sign.
Parameters:
points: The points, in order: at least 2, each output finite and each input finite or NaN.count: The number of points.easingOut: Receives the easing, in mode mtwn_easeIn; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or points outside the above, leaving the points as they were.
Thread safety. Safe from any thread; the points are used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeRoughEasing(const mtwnRoughDef* def, mtwnLinearPoint* pointsOut, uint32_t count, mtwnEasing* easingOut);
Makes a rough easing: linear() through points that wander from a shape by a seed, as GSAP's RoughEase and anime.js's irregular, the same curve for a seed on every platform. The first point is (0, 0) and the last (1, 1); the k-th of the m inner points falls at a seeded input in [k/m, (k+1)/m), so they stay in order, and its output is the shape there plus a seeded offset of at most the strength either side, by the taper.
Parameters:
def: The rough easing.pointsOut: Receives the points, which the easing references: they must outlive it and not change. Unchanged on failure: the shape is sampled at every inner point before one is written, so only a host shape that gives a value not finite when sampled again there leaves them unspecified.count: The number of points, at least 2.easingOut: Receives the easing, in mode mtwn_easeIn; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a shape no maker produced, fewer than 2 points, a strength below 0 or not finite, an unknown taper or flag, or a shape giving a value not finite.
Thread safety. Safe from any thread; the points are used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSetEaseMode(mtwnEasing* easing, mtwnEaseMode mode);
Changes an easing's mode, keeping its curve.
Parameters:
easing: An easing made by this library.mode: The mode.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an easing no maker produced or an unknown mode, leaving the easing as it was.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnIsEasingMonotonic(const mtwnEasing* easing, bool* monotonicOut);
Tells whether an easing never decreases, as a timeline's easing must: linear, power, sine, expo, circ and steps in every mode, a cubic bezier with both y from 0 to 1, linear() with outputs that never decrease, in in-out ending at 1 or below and in out-in starting at 0 or above, since those modes join the curve's halves at 1/2; not back, elastic, bounce or a spring, and not a host function, which the library cannot inspect. Each of these samples to values that never decrease, but a cubic bezier through mtwnSampleEasing, solved to 1e-14 in x, whose values can fall an ulp or so short of the last, more near a vertical tangent. A timeline samples one so that they never do, which can differ from what the same easing gives in a keyframe, a transition or mtwnSampleEasing by a few 1e-14 for CSS's keywords.
Parameters:
easing: An easing made by this library.monotonicOut: Receives whether it never decreases; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or an easing no maker produced.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleEasing(const mtwnEasing* easing, double progress, bool before, double* easedOut);
Samples an easing. CSS's curves follow CSS Easing Level 2 outside 0 to 1; Penner's curves, springs and host functions see progress clamped to 0 to 1. The modes reflect the curve, and the before flag reaches it where it samples progress unreflected.
Every curve but a host function's gives a finite value: CSS's, past the doubles' range, the largest finite double of its sign. A host function's infinity is given as it is, and its NaN never: the progress it was called with is taken instead (mtwnMakeHostEasing).
Parameters:
easing: An easing made by this library.progress: The progress, finite.before: Whether the timing is in its before phase; it moves only curves that jump at their start.easedOut: Receives the eased progress: exactly 0 at 0 and 1 at 1 for Penner's curves, springs, linear and cubic bezier; what CSS defines for steps and linear(). Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an easing no maker produced or a progress not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleCubicBezierEasing(const mtwnEasing* easing, double progress, double* easedOut);
Samples a cubic bezier easing as mtwnSampleEasing does, to the bit, in each mode, reaching none of the other curves. With link-time optimization, or with -ffunction-sections and --gc-sections, a program that samples cubic beziers only through it links none of mtwnSampleEasing's dispatch, Penner's curves or the spring easing; without either, the makers and mtwnSetEaseMode bring them along.
Parameters:
easing: An easing made by mtwnMakeCubicBezierEasing or mtwnMakeCssEasing, its mode set by mtwnSetEaseMode, or the linear easing.progress: The progress, finite; outside 0 to 1 the curve follows CSS Easing Level 2.easedOut: Receives what mtwnSampleEasing gives with before false: the progress for the linear easing. Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an easing of another kind or no maker produced, or a progress not finite.
Thread safety. Safe from any thread.
event.hEvents: records in the context's bounded queue, never callbacks. Each update appends what its players crossed, at most one record per player, node or mark, kind and direction, with the count of crossings, ordered by the time of the first crossing, then the players' creation order, then the clip's order; the host reads them when it likes. The queue holds the context def's eventCapacity records. One that arrives at a full queue is dropped and counted, never silently: mtwnContext_ReadEvents reports the drops since the last read, and mtwnContext_GetEventsDropped all of them. Records arrive in the order they are made (players in creation order, each player's nodes in clip order), so a full queue keeps the first made and drops the rest of an update's; those kept are sorted. A context of eventCapacity 0 makes no records and drops none: its clips' players skip the sweeps that find crossings, the cost of the records.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_ReadEvents(mtwnContext* context, mtwnEvent* eventsOut, uint32_t capacity, uint32_t* countOut, uint64_t* droppedOut);
Takes the oldest records off the queue, as many as fit, and reports how many were dropped at a full queue since the last read.
Parameters:
context: The context.eventsOut: Receives the records; NULL only with a capacity of 0. On failure its first capacity records, up to the context's event capacity, are zero; a null context, or a call back in from the context's own host code (mtwn_errorBusy), leaves it as it was.capacity: Its length.countOut: Receives how many were taken; 0 on failure but a call back in (mtwn_errorBusy), which leaves it.droppedOut: Receives the records dropped since the last read (the count then starts again); may be NULL; 0 on failure but a call back in (mtwn_errorBusy), which leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null context or countOut, or a null array with a capacity.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint32_t mtwnContext_GetEventCount(const mtwnContext* context);
Returns how many records waited in the queue, not yet taken.
Parameters:
context: The context.Returns: The count; 0 for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
uint64_t mtwnContext_GetEventsDropped(const mtwnContext* context);
Returns how many records were dropped since the context was made, each arriving at a full queue (its capacity is the context def's eventCapacity).
Parameters:
context: The context.Returns: The count; 0 for a null context.
Thread safety. Safe from any thread; the context is used by one thread at a time.
interpolate.hInterpolation of values that are not plain numbers: colors in a named space as CSS Color 4 interpolates them, angles with CSS's hue methods, rotations by slerp, integers and discrete values, and punch and shake, the signals a host adds to a value. A mix's sampler checks its fields by their ranges, not by making the mix again, which would cost as much as the sample. A mix that passes the check gives no undefined behavior and no NaN; it is not promised to equal what a maker would give. A color or rotation is finite, held within the floats as a target holds it; a scale or zoom reaches infinity or 0 only past the doubles' range, as a maker's mix does.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeColorMix(mtwnColor from, mtwnColor to, mtwnColorSpace space, mtwnHueMethod hue, mtwnColorMix* mixOut);
Makes the interpolation between two colors in a space, following CSS Color 4: a powerless OkLCh hue (chroma at most 0.000004) takes the other color's, its chroma kept as CSS's sample code keeps it where Color 4's text sets it to 0, the hues are fixed up by the method, and the colors are premultiplied, the hue excepted.
Parameters:
from: The color at progress 0: finite, alpha from 0 to 1.to: The color at progress 1, likewise.space: The space to interpolate in.hue: The hue method, read for OkLCh only.mixOut: Receives the mix; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown space or method, or a color outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixColor(const mtwnColorMix* mix, double progress, mtwnColor* colorOut);
Samples a mix: its colors exactly at 0 and 1, between them the premultiplied coordinates interpolated and divided by the interpolated alpha, or kept as they are where that alpha is 0 or below. Progress outside 0 to 1 extends the line, with alpha clamped to 0 to 1; the channels are not clamped, but a channel past the floats' range is held at the largest finite float of its sign, in every space. So far out that an OkLCh hue passes the doubles, it counts as 0.
Parameters:
mix: A mix made by this library, or one whose fields pass its check (this header's opening).progress: The progress, finite.colorOut: Receives the color; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a progress not finite, or a mix whose space is unknown, whose padding is not 0, whose colors mtwnMakeColorMix would refuse, or whose ends have a coordinate not finite, an alpha not their color's, or an OkLCh hue outside 0 to 4 pi.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnConvertColorToSpace(mtwnColor color, mtwnColorSpace space, double coordinatesOut[4]);
Converts a color to a space's coordinates and its alpha, for a host that springs or composes in the space.
Parameters:
color: Finite, alpha from 0 to 1.space: The space.coordinatesOut: Receives the three coordinates and the alpha; an OkLCh hue in radians from 0 to 2 pi (CSS's degrees times pi / 180), NaN where it is powerless; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown space or a color outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnConvertColorFromSpace(const double coordinates[4], mtwnColorSpace space, mtwnColor* colorOut);
Converts a space's coordinates and an alpha back to a color.
Parameters:
coordinates: The three coordinates and the alpha; a NaN OkLCh hue counts as 0, as CSS's missing hue does.space: The space.colorOut: Receives the color, alpha clamped to 0 to 1, a channel past the floats' range held at the largest finite float of its sign; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown space, or a coordinate or alpha not finite, a NaN hue excepted.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixAngle(double from, double to, mtwnAngleMethod method, double progress, double* angleOut);
Interpolates an angle in radians: the end at progress 1 is moved by whole turns as the method asks, then the two are interpolated linearly. At 0 the result is from exactly, and at 1 to exactly when no turn was added.
Parameters:
from: The angle at progress 0, finite.to: The angle at progress 1, finite.method: The method.progress: The progress, finite; outside 0 to 1 extends.angleOut: Receives the angle; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null angleOut, an unknown method, or an angle or progress not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeRotationMix(mtwnQuat from, mtwnQuat to, mtwnRotationPath path, mtwnRotationMix* mixOut);
Makes the spherical interpolation between two rotations, at constant angular speed, the shortest way or the longest.
Parameters:
from: The rotation at progress 0: finite, not zero; it is normalized.to: The rotation at progress 1, likewise.path: Which way.mixOut: Receives the mix; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an unknown path, a rotation outside the above, or the longest way between rotations so close (|q0 + q1| under 1e-6 once the path's sign is taken) that it turns a full circle about no defined axis.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixRotation(const mtwnRotationMix* mix, double progress, mtwnQuat* rotationOut);
Samples a rotation mix: its rotations normalized exactly at 0 and 1 (the second negated when the path needed it), between and beyond them slerp, of unit length to a float's rounding; ends of one rotation stay at any progress.
Parameters:
mix: A mix made by this library, or one whose fields pass its check (this header's opening).progress: The progress, finite.rotationOut: Receives the rotation; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a progress not finite, or a mix whose ends are not of unit length to within their normalization's rounding (12 times 2^-53 in the squared length) or not stored as their floats, or whose angle is outside 0 to pi.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeScaleMix(double from, double to, mtwnScaleMix* mixOut);
Makes the geometric interpolation between two scales.
Parameters:
from: The scale at progress 0, finite and above 0.to: The scale at progress 1, likewise.mixOut: Receives the mix; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a scale outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixScale(const mtwnScaleMix* mix, double progress, double* scaleOut);
Samples a scale mix: from (to / from)^progress, exactly from at 0 and to at 1; outside 0 to 1 it extends, to infinity or 0 past the doubles' range.
Parameters:
mix: A mix made by this library, or one whose fields pass its check (this header's opening).progress: The progress, finite.scaleOut: Receives the scale; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a progress not finite, or a mix whose ends are not finite and above 0 or whose logarithms are not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeZoomMix(mtwnZoomView from, mtwnZoomView to, double rho, mtwnZoomMix* mixOut);
Makes the zoom and pan between two views that van Wijk and Nuij found optimal ("Smooth and efficient zooming and panning", 2003): it zooms out as far as the pan needs and back in, so the eye can follow; with the centers equal it is a geometric zoom.
Parameters:
from: The view at progress 0: finite, its width above 0.to: The view at progress 1, likewise.rho: How much it zooms out against panning, finite and above 0: the paper's measured sqrt(2) (d3's default), 1.42 (Mapbox's); toward 0 it pans with little zoom.mixOut: Receives the mix; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a view or rho outside the above, or views whose path leaves the doubles' range (widths, or a pan against the width, about 1e150 times apart).
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixZoom(const mtwnZoomMix* mix, double progress, mtwnZoomView* viewOut);
Samples a zoom mix: exactly from at 0 and to at 1, between them the path at that share of its length; outside 0 to 1 it extends, its width going to 0 as its center settles on a point either way (an infinity where that point is past the doubles' range), never NaN.
Parameters:
mix: A mix made by this library, or one whose fields pass its check (this header's opening).progress: The progress, finite.viewOut: Receives the view; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a progress not finite, or a mix outside its check: views as mtwnMakeZoomMix takes them with a finite difference between their centers, rho finite and above 0, a length finite and not below 0, r0 within 700 of 0, cosh r0 finite and at least 1, a finite pan's scale, and with a pan's scale of 0 widths whose scale mix passes its check and runs from one view's width to the other's.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeZoomLength(const mtwnZoomMix* mix, double* lengthOut);
A zoom mix's path length, the paper's S: a zoom by a factor of e with no pan is 1 / rho long. The measure a duration is taken from (d3 takes S rho / sqrt(2) seconds); 0 for equal views.
Parameters:
mix: A mix made by this library, or one whose fields pass its check (this header's opening).lengthOut: Receives the length; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a mix mtwnMixZoom refuses.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixInteger(int64_t from, int64_t to, double progress, int64_t* valueOut);
Interpolates an integer: the interpolation in double, rounded to nearest with ties away from zero, so it passes through every integer between. Exact at the ends, and between them for values within 2^53.
Parameters:
from: The value at progress 0.to: The value at progress 1.progress: The progress, finite; outside 0 to 1 extends, clamped to the type's range.valueOut: Receives the value; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null valueOut or a progress not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMixDiscrete(uint32_t from, uint32_t to, double progress, uint32_t* valueOut);
Interpolates a discrete value the host indexes (an enumeration, a flag): from below progress 1/2, to from it, as Web Animations steps values it cannot interpolate.
Parameters:
from: The value at progress 0.to: The value at progress 1.progress: The progress, finite.valueOut: Receives from or to; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null valueOut or a progress not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakePunch(double frequency, double duration, double exponent, mtwnPunch* punchOut);
Makes a punch.
Parameters:
frequency: Cycles a second, finite and above 0 (DOTween's vibrato over the duration).duration: Seconds, finite and above 0.exponent: The envelope's, finite and above 0: 1 fades linearly, above 1 sooner, below 1 later.punchOut: Receives the punch; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a parameter outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSamplePunch(const mtwnPunch* punch, double seconds, double* factorOut);
Samples a punch: a factor from -1 to 1 the host scales by each channel's amplitude and adds to the value; exactly 0 at 0, at the duration and outside them.
Parameters:
punch: A punch made by this library.seconds: The time since its start, not NaN.factorOut: Receives the factor; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a punch whose fields mtwnMakePunch would refuse, or a NaN time.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeShake(double frequency, double duration, double exponent, uint64_t seed, mtwnShake* shakeOut);
Makes a shake.
Parameters:
frequency: Lattice points a second, finite and above 0: how often the noise changes direction.duration: Seconds, finite and above 0, with the frequency fewer than 2^53 lattice points.exponent: The envelope's, finite and above 0.seed: Any value; the same seed shakes the same way.shakeOut: Receives the shake; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a parameter outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleShake(const mtwnShake* shake, uint32_t channel, double seconds, double* factorOut);
Samples a shake for one channel: a factor from -1 to 1, each channel its own noise; exactly 0 at 0, at the duration and outside them.
Parameters:
shake: A shake made by this library.channel: Which channel, any value.seconds: The time since its start, not NaN.factorOut: Receives the factor; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a shake whose fields mtwnMakeShake would refuse, or a NaN time.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleShakeNoise(const mtwnShake* shake, uint32_t channel, double seconds, double* factorOut);
Samples a shake's noise alone, its envelope left to the host: for a shake driven by "trauma" (Eiserloh's camera shake: an amount the host raises at each hit and lets decay, the shake its square), on a clock that runs on through the hits, so the noise never jumps where the amplitude changes. Each channel its own noise.
Parameters:
shake: A shake made by this library; its duration and exponent are checked but not used.channel: Which channel, any value.seconds: The clock, from 0 while the frequency times it is below 2^53; not NaN.factorOut: Receives a factor from -1 to 1: 0 on the lattice points and outside the clock's range; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a shake whose fields mtwnMakeShake would refuse, or a NaN clock.
Thread safety. Safe from any thread.
path.hPaths and tracks: keyframe curves of one to four channels, segment by segment linear, step, cubic Bezier or Catmull-Rom (centripetal by default), timed by their keyframes or traveled at constant speed by arc length; and tracks, which give every value kind its keyframes. Both reference the caller's arrays and allocate nothing.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakePath(const mtwnKeyframe* keyframes, uint32_t count, uint8_t channels, double alpha, double* lengthsOut, mtwnPath* pathOut);
Makes a path. With lengths it travels at constant speed: the cumulative arc length at each keyframe is measured into them, and a progress is a share of the whole length, the keyframes' offsets and easings no longer timing it. Each segment's length is within about 1e-11 of it relative, and a point at constant speed within about 1e-11 of its segment's length.
Parameters:
keyframes: At least 2: offsets finite, not decreasing, the first 0 and the last 1; values finite in the path's channels, and Bezier controls too; known kinds.count: The number of keyframes.channels: From 1 to 4.alpha: Catmull-Rom's knot exponent from 0 to 1: 0.5 centripetal (no cusps or self-intersections within a segment), 0 uniform, 1 chordal.lengthsOut: Count doubles for constant speed, or NULL. Every segment but the last keyframe's then may not be a step, which has no length to travel; unchanged on failure.pathOut: Receives the path; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or an argument outside the above.
Thread safety. Safe from any thread; the lengths are used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSamplePath(const mtwnPath* path, double progress, double valueOut[4], double tangentOut[4]);
Samples a path: the segment a progress falls in (the last keyframe at or below it; past the ends the first or last segment extended), its local progress eased by the segment's easing, then its kind; or at constant speed the point at that share of the length.
Parameters:
path: A path made by this library.progress: The progress, finite.valueOut: Receives the path's channels, 0 past them; unchanged on failure.tangentOut: Receives the segment's derivative by its own parameter there, not normalized, for orienting along the path; may be NULL; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null path or valueOut, a path or segment no maker produced, or a progress not finite.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputePathDirection(const mtwnPath* path, double progress, double directionOut[4]);
Gives a path's direction at a progress, as SVG 2's path directionality and CSS's offset-rotate: auto take it: a unit vector in its channels, 0 past them. Within a segment the curve's direction; at a keyframe the later segment's. A step or a segment of no length (coincident keyframes, a hold) takes the direction of the nearest segment after it with a length, at its start, as SVG 2 moves past a segment of no length; with none after it, at the path's end, of the nearest before it, at its end; a path of no length points along the first channel. Where the derivative is 0 (a Bezier control on its end, a cusp), the first non-zero of the second and third derivatives, the outgoing direction: SVG 2 leaves a cusp's direction open, so that choice is this library's. Chrome takes the incoming direction at every boundary, against SVG 2's text. A scale's is in its logarithm; at constant speed the progress is the share of the length.
Parameters:
path: A path made by this library.progress: The progress, finite.directionOut: Receives the direction; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid as mtwnSamplePath refuses, or for a null directionOut.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputePathAngle(const mtwnPath* path, double progress, double* angleOut);
Gives the angle of a path's direction (mtwnComputePathDirection) in its first two channels, atan2(y, x) by the library's own arctangent, the same on every platform: what CSS's offset-rotate: auto turns by. Reversed, add pi; a fixed turn, add it.
Parameters:
path: A path made by this library.progress: The progress, finite.angleOut: Receives radians, from -pi to pi; 0 or pi for one channel; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid as mtwnSamplePath refuses, or for a null angleOut.
Thread safety. Safe from any thread.
static inline mtwnTrackDef mtwnDefaultTrackDef(mtwnValueKind kind);
Makes a track def for a kind: centripetal Catmull-Rom, colors in Oklab with the shorter hue, angles the shorter way, rotations the shortest.
Parameters:
kind: The kind.Returns: The def.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeTrack(mtwnKeyframe* keyframes, uint32_t count, const mtwnTrackDef* def, double* lengthsOut, mtwnSegmentMix* mixesOut, mtwnTrack* trackOut);
Makes a track. Numbers and vectors are their path; integers the path rounded to nearest, ties away from zero; discrete values step at an eased 1/2 of a linear segment, or hold through a step. Angles are unwrapped in place, each keyframe (with its controls) moved by the method's whole turns from the one before. Colors mix linear segments in the def's space and hold through steps. Rotations slerp linear segments, hold through steps, and take Bezier and Catmull-Rom per component, normalized after; with the shortest path the keyframes and controls are first flipped in place into the hemisphere of the one before. Scales are a path over their logarithms (the path's own samples are logarithms): linear segments their scale mix, the others the exponential of their curve, every keyframe exact, and at constant speed equal ratios in equal times. On failure the keyframes are as they were.
Parameters:
keyframes: As mtwnMakePath takes them, in the kind's channels; a rotation not all zero; a color's alpha from 0 to 1; a scale's value, and a Bezier segment's controls, above 0. Colors and discrete values take linear and step segments only. Rewritten in place for angles and rotations on the shortest path (unwrapped, flipped), so one array must not feed two tracks with different angle methods or rotation paths; a clip copies them first.count: The number of keyframes.def: The def: a known kind, alpha from 0 to 1, known choices, those its kind does not read too.lengthsOut: Count doubles for constant speed, or NULL; only numbers, vectors, angles, integers and scales take it (a scale's lengths are its logarithm's); unchanged on failure.mixesOut: Count - 1 mixes for colors and rotations, else NULL or unused; unchanged on failure.trackOut: Receives the track; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or an argument outside the above.
Thread safety. Safe from any thread; the keyframes are used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleTrack(const mtwnTrack* track, double progress, mtwnVec4* valueOut);
Samples a track: its value at a progress, as mtwnSamplePath finds the segment and eases it.
Parameters:
track: A track made by this library.progress: The progress, finite.valueOut: Receives the value, the kind's channels used and the rest 0; a number past the floats' range held at the nearest finite float, as a target holds it; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null track or valueOut, a track or segment no maker produced, or a progress not finite.
Thread safety. Safe from any thread.
player.hPlayers: what writes targets. A player plays a sealed clip on targets bound to its slots, by Web Animations' procedures on the host's clock; a transition is a player too. A player not kept ends by committing its last value into its targets' base values and is then freed, its id stale.
static inline mtwnBinding mtwnMakeBinding(uint32_t slot, mtwnTargetId target);
Makes a binding of a slot to a target: replace, at full weight.
Parameters:
slot: The clip's slot.target: The target.Returns: The binding.
Thread safety. Safe from any thread.
static inline mtwnClipPlayerDef mtwnDefaultClipPlayerDef(void);
Makes a player def: no clip, no bindings, playing at once at rate 1 and full weight, freed when it ends.
Returns: The def.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnCreateClipPlayer(mtwnContext* context, const mtwnClipPlayerDef* def, mtwnPlayerId* playerOut);
Makes a player of a sealed clip, which it holds busy until it is freed; it starts at the next update if the def says play, else idle.
Parameters:
context: The context.def: The def.playerOut: Receives the player's id, or the null id on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a def without its cookie, a rate NaN, a weight outside [0, 1], a binding outside the above; mtwn_errorLimit for a rate above MTWN_RATE_LIMIT in size, or other than 0 below MTWN_MIN_RATE; mtwn_errorStale for a clip that is not alive; mtwn_errorState for one not sealed; mtwn_errorCapacity when the context holds its capacity of players or of bindings. Whether a slot is bound twice is checked last, after the rate's limit and the capacities: a def that binds a slot twice gets mtwn_errorLimit or mtwn_errorCapacity where either applies. The checks take time linear in the bindings and the clip's slots.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Play(mtwnContext* context, mtwnPlayerId player);
Plays a clip's player, as Web Animations plays an animation with auto-rewind: from the start (or the end, backwards) when idle, at its end or before its start; a paused player resumes. One that needs a start time takes the next update's.
Parameters:
context: The context.player: A clip's player.Returns: mtwn_success; mtwn_errorInvalid for a null context; mtwn_errorStale for an id that names no live player; mtwn_errorInvalid for a transition; mtwn_errorState backwards from an end that is infinite.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Pause(mtwnContext* context, mtwnPlayerId player);
Pauses a clip's player at its current time, or at its start (its end, backwards) when idle.
Parameters:
context: The context.player: A clip's player.Returns: As mtwnClipPlayer_Play.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Reverse(mtwnContext* context, mtwnPlayerId player);
Reverses a clip's player: negates its rate, keeping its current time, and plays it with auto-rewind; refused, and nothing changed, when that would play an infinite clip backwards from its end.
Parameters:
context: The context.player: A clip's player.Returns: As mtwnClipPlayer_Play.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Finish(mtwnContext* context, mtwnPlayerId player);
Finishes a clip's player: its current time goes to the end of its playback direction, the clip's end forwards, 0 backwards, crossing what lies before it, its records at once.
Parameters:
context: The context.player: A clip's player.Returns: As mtwnClipPlayer_Play; mtwn_errorState also for a rate of 0 or an infinite clip played forwards.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Cancel(mtwnContext* context, mtwnPlayerId player);
Cancels a clip's player: it becomes idle, without effect, and is kept, to be played again; a cancel record says so if it had a time.
Parameters:
context: The context.player: A clip's player.Returns: As mtwnClipPlayer_Play.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Seek(mtwnContext* context, mtwnPlayerId player, double seconds);
Seeks a clip's player to a current time, jumping: what lies between is not crossed, and a seek record says so (mtwnClipPlayer_Sweep crosses it). Seeks by progress and label jump too.
Parameters:
context: The context.player: A clip's player.seconds: The time into the clip, at most MTWN_SEEK_LIMIT in size.Returns: As mtwnClipPlayer_Play; mtwn_errorInvalid also for a NaN time; mtwn_errorLimit for one past MTWN_SEEK_LIMIT in size, infinity included.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_Sweep(mtwnContext* context, mtwnPlayerId player, double seconds);
Seeks a clip's player to a time crossing everything between, as an update sweeping there would: its records come at once, at the last update's time. A seek otherwise jumps, leaving a seek record.
Parameters:
context: The context.player: A clip's player.seconds: The time into the clip, at most MTWN_SEEK_LIMIT in size.Returns: As mtwnClipPlayer_Seek.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_SeekProgress(mtwnContext* context, mtwnPlayerId player, double progress);
Seeks a clip's player to a share of its clip's duration.
Parameters:
context: The context.player: A clip's player.progress: The share, not NaN; the duration must be finite.Returns: As mtwnClipPlayer_Seek, mtwn_errorLimit for a time, the share times the duration, past MTWN_SEEK_LIMIT in size; mtwn_errorInvalid also for an infinite duration.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_SeekLabel(mtwnContext* context, mtwnPlayerId player, uint32_t key);
Seeks a clip's player to a label of its clip's root.
Parameters:
context: The context.player: A clip's player.key: The label's key.Returns: As mtwnClipPlayer_Play; mtwn_errorInvalid also for no such label; mtwn_errorLimit for one past MTWN_SEEK_LIMIT in size.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_SetRate(mtwnContext* context, mtwnPlayerId player, double rate);
Sets a clip's player's rate, keeping its current time: as Web Animations' seamless update of the playback rate keeps it, by the start time, so to within an ulp of the host time times the rate (see MTWN_RATE_LIMIT). A moving player takes the rate at the next update; an idle or paused one at once. A finished player runs at the new rate from the time it holds, its start time set again from it: a positive rate keeps it finished there, a negative one plays it back from there at once, as Chrome does. Web Animations' procedures differ there (docs/internals/timing.md).
Parameters:
context: The context.player: A clip's player.rate: 0, which holds, or from MTWN_MIN_RATE to MTWN_RATE_LIMIT in size; negative plays backwards. NaN is refused with mtwn_errorInvalid and another with mtwn_errorLimit, as misuse, the player unchanged.Returns: As mtwnClipPlayer_Play; mtwn_errorInvalid also for a NaN rate; mtwn_errorLimit for a rate other than 0 outside [MTWN_MIN_RATE, MTWN_RATE_LIMIT] in size.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_SetWeight(mtwnContext* context, mtwnPlayerId player, float weight);
Sets a clip's player's weight, which scales its bindings' from the next update: a layer faded in or out.
Parameters:
context: The context.player: A clip's player.weight: In [0, 1].Returns: As mtwnClipPlayer_Play; mtwn_errorInvalid also for a weight outside [0, 1].
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnClipPlayer_GetState(const mtwnContext* context, mtwnPlayerId player, mtwnClipPlayerState* stateOut);
Reads a clip's player's state at the last update's time.
Parameters:
context: The context.player: A clip's player.stateOut: Receives the state, zero on failure but mtwn_errorBusy, which leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null context or stateOut; mtwn_errorStale for an id that names no live player; mtwn_errorInvalid for a transition; mtwn_errorBusy when called from the host's code while the update's clip players run on its task system, which may be writing what the call reads.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnDestroyPlayer(mtwnContext* context, mtwnPlayerId player);
Stops a player without committing: its targets show their base values again at once.
Parameters:
context: The context.player: The player.Returns: mtwn_success; mtwn_errorInvalid for a null context; mtwn_errorStale for an id that names no live player, as one that ended does: not counted as misuse for an id the context handed out, a kept player's too, since a player may free itself at an end the update decides, but counted for one never handed out, the null id among them.
Thread safety. Safe from any thread; the context is used by one thread at a time.
bool mtwnPlayer_IsValid(const mtwnContext* context, mtwnPlayerId player);
Tells whether an id names a live player: one that has not ended, been replaced or been destroyed. Not counted as misuse.
Parameters:
context: The context, or NULL.player: The id.Returns: Whether the player is alive.
Thread safety. Safe from any thread; the context is used by one thread at a time.
sample.hSampling: an easing turned into points in caller memory, as an even table for a GPU or a host lookup, or as the points of a CSS linear() fitted to a tolerance. Nothing is allocated.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleEasingTable(const mtwnEasing* easing, uint32_t count, float* valuesOut);
Samples an easing evenly over progress 0 to 1: valuesOut[i] is the eased progress at i / (count - 1), rounded to float, a value past the floats' range held at the largest finite float of its sign (a host function's infinity too; its NaN is taken as the progress, as mtwnMakeHostEasing says), so every value is finite.
Parameters:
easing: An easing made by this library.count: The number of samples, at least 2.valuesOut: Receives count values; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, an easing no maker produced or a count below 2.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnFitLinearEasing(const mtwnEasing* easing, double tolerance, mtwnLinearPoint* pointsOut, uint32_t capacity, uint32_t* countOut);
Fits CSS linear() points to an easing over progress 0 to 1: their interpolation is within the tolerance of the eased progress at every probe, 32 inside each segment, and is not proven so between them; the points lie on the curve, the first at 0 and the last at 1. A segment narrower than 2^-24 is kept as it is, so a host function's jump costs points and may stay over the tolerance within 2^-24 of it. Steps are refused: CSS writes them as steps().
Parameters:
easing: An easing made by this library, not steps.tolerance: The largest error allowed, finite and above 0.pointsOut: Receives the points, with their inputs; may be NULL when capacity is 0. The fit writes them as it finds them, so on failure it holds the fit's first points, at most capacity, exactly as a larger buffer would start, and the rest as it was.capacity: The number of points pointsOut holds.countOut: Receives the number of points the fit has, also when they do not fit; unchanged on the other failures.Returns: mtwn_success; mtwn_errorCapacity when more than capacity points are needed; mtwn_errorLimit when more than MTWN_MAX_FIT_POINTS are, the fit stopped there and countOut 0; mtwn_errorInvalid for a null easing or countOut, an easing no maker produced, a NULL pointsOut with a capacity, steps, a tolerance outside the above, or an easing not finite at a point the fit keeps.
Thread safety. Safe from any thread.
spring.hSprings, decay and the rubber band: a damped spring pulling a value to its target, and a velocity decaying to rest, both solved in closed form from where they start, so the same times give the same values at every frame rate; and iOS's rubber band for dragging past a limit. A spring's start is an offset from the target and a velocity, in the value's units (per second); a retarget keeps the velocity and changes the offset.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeSpring(double stiffness, double damping, double mass, mtwnSpring* springOut);
Makes a spring from its physical parameters: natural frequency sqrt(stiffness / mass), damping ratio damping / (2 sqrt(stiffness mass)).
Parameters:
stiffness: Finite and above 0.damping: Finite and at least 0.mass: Finite and above 0.springOut: Receives the spring; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a parameter outside the above or giving a frequency outside the finite range above 0.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeSpringFromFrequency(double hertz, double dampingRatio, mtwnSpring* springOut);
Makes a spring from its natural frequency in hertz and its damping ratio: 1 is critical, below it overshoots, 0 never settles.
Parameters:
hertz: Finite and above 0.dampingRatio: Finite and at least 0.springOut: Receives the spring; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a parameter outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeSpringFromDuration(double duration, double bounce, mtwnSpring* springOut);
Makes a spring from Apple's perceptual duration and bounce, as SwiftUI, Motion and anime.js map them: natural frequency 2 pi / duration, damping ratio 1 - bounce for a bounce from 0, 1 / (1 + bounce) below it.
Parameters:
duration: Seconds, finite and above 0.bounce: Above -1 and at most 1: 0 is critical, 1 never settles, below 0 is overdamped.springOut: Receives the spring; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a parameter outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeSpringMotion(const mtwnSpring* spring, double seconds, mtwnSpringMotion* motionOut);
Computes how a spring moves any start over a time, for applying to every channel of a value.
Parameters:
spring: A spring made by this library.seconds: The time since the start, at least 0; infinity gives the rest, all four zero when the spring is damped.motionOut: Receives the motion; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a spring no maker produced, or a time outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleSpring(const mtwnSpring* spring, double offset, double velocity, double seconds, double* offsetOut, double* velocityOut);
Samples a spring from a start.
Parameters:
spring: A spring made by this library.offset: The start's offset from the target, finite.velocity: The start's velocity, per second, finite.seconds: The time since the start, at least 0; infinity gives the rest.offsetOut: Receives the offset then; may be NULL; unchanged on failure.velocityOut: Receives the velocity then; may be NULL; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null spring, a spring no maker produced, or a start or time outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeSpringSettlingTime(const mtwnSpring* spring, double offset, double velocity, double offsetTolerance, double velocityTolerance, double* secondsOut);
Returns the time after which a spring from a start, sampled by mtwnSampleSpring, stays within both tolerances of its target and of rest, by bounds on its offset and velocity that never end it early, less a margin for the sample's rounding; the host then snaps it to the target. For tolerances near the subnormals, that margin can make it noticeably later than the motion's own.
Parameters:
spring: A spring made by this library.offset: The start's offset from the target, finite.velocity: The start's velocity, per second, finite.offsetTolerance: How far from the target is at rest, above 0.velocityTolerance: How fast is at rest, per second, above 0.secondsOut: Receives the seconds from the start: 0 when it starts within both by more than the margin for the sample's rounding (relatively about 1e-14, up to about 4e-9 just above critical damping; closer to a tolerance, a time just past 0); infinity for an undamped spring that does not, and for a spring decaying at a rate below about 4e-306 that does not, where the sample's rounding below the normal doubles, times the start, could pass a tolerance. On any spring, a start within a tolerance only a few subnormal steps wide gets 0 yet can sample one subnormal step past it, only through rounding ties. Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a spring no maker produced, or a start or tolerance outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeSpringEasing(const mtwnSpring* spring, double duration, double velocity, mtwnEaseMode mode, mtwnEasing* easingOut);
Makes an easing of a spring over a duration: the spring from an offset of -1 with a start velocity, sampled at progress times the duration and divided by its value at the duration, so it is exactly 0 at 0 and 1 at 1; a spring settled by then is changed by the distance it had left. For CSS linear() (mtwnFitLinearEasing) and for tracks timed by duration. An underdamped spring oscillating faster than once in 2^-10 of the duration is refused, as an elastic's period is: a fit of MTWN_MAX_FIT_POINTS points could not follow it. So is one whose eased progress could pass the doubles' range, as a spring almost back at its start at the duration has, divided by its value there. So is one whose natural frequency, in radians a second, times the duration reaches 2^512 (about 1.34e154): its square, the easing's squared frequency, would pass the doubles' range, as mtwnMakeSpring refuses a spring whose own would. Only an overdamped or critical spring reaches it, an oscillating one being refused far sooner.
Parameters:
spring: A spring made by this library.duration: Seconds, finite and above 0.velocity: The start velocity in units of the whole change a second, finite: 0 from rest.mode: The mode.easingOut: Receives the easing; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a spring no maker produced, an unknown mode, a duration or velocity outside the above, a spring back at its start at the duration, or one of the three above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeDecay(double rate, mtwnDecay* decayOut);
Makes a decay whose velocity falls as e^(-rate t).
Parameters:
rate: The rate a second, finite and above 0.decayOut: Receives the decay; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a rate outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeDecayFromDeceleration(double perMillisecond, mtwnDecay* decayOut);
Makes a decay from iOS's deceleration rate, the share of velocity kept each millisecond (0.998 normal, 0.99 fast): the rate a second is -1000 ln of it.
Parameters:
perMillisecond: Above 0 and below 1.decayOut: Receives the decay; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a share outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleDecay(const mtwnDecay* decay, double position, double velocity, double seconds, double* positionOut, double* velocityOut);
Samples a decay from a start: the position is position + velocity (1 - e^(-k t)) / k, the velocity velocity e^(-k t).
Parameters:
decay: A decay made by this library.position: The start's position, finite.velocity: The start's velocity, per second, finite.seconds: The time since the start, at least 0; infinity gives the rest.positionOut: Receives the position then; may be NULL; unchanged on failure.velocityOut: Receives the velocity then; may be NULL; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null decay, a decay no maker produced, or a start or time outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeDecayStopTime(const mtwnDecay* decay, double velocity, double stopSpeed, double* secondsOut);
Returns the time a decay's speed falls to a stop speed.
Parameters:
decay: A decay made by this library.velocity: The start's velocity, per second, finite.stopSpeed: The speed counted as stopped, per second, above 0.secondsOut: Receives the seconds from the start: 0 when the start is no faster. Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a decay no maker produced, or a velocity or stop speed outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeDecayCrossingTime(const mtwnDecay* decay, double position, double velocity, double target, double* secondsOut);
Returns the time a decay reaches a position, where a host hands it over to a spring back from a limit.
Parameters:
decay: A decay made by this library.position: The start's position, finite.velocity: The start's velocity, per second, finite.target: The position to reach, finite.secondsOut: Receives the seconds from the start: 0 when it starts there; infinity when it never gets there, moving away or coming to rest short of it or exactly on it. Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a decay no maker produced, or a value outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeDecayToRest(double position, double velocity, double rest, mtwnDecay* decayOut);
Makes the decay that comes to rest at an end from a start, keeping the start's velocity: its rate is velocity / (end - position). With mtwnSampleDecay's rest (seconds infinite) as the natural end, a host snaps a fling: it chooses the end, a page or a grid point near the natural one, and lands there.
Parameters:
position: The start's position.velocity: The start's velocity, per second.rest: The end to come to rest at.decayOut: Receives the decay; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a value not finite, an end the velocity does not move toward (behind the start, at it, or a velocity of 0), or a rate that overflows.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnMakeBoundedDecay(const mtwnDecay* decay, const mtwnSpring* spring, double lower, double upper, mtwnBoundedDecay* boundedOut);
Makes a bounded decay.
Parameters:
decay: A decay made by this library.spring: A spring made by this library, the bounce.lower: The lower bound; may be -infinity, for none.upper: The upper bound, at least the lower; may be infinity, for none.boundedOut: Receives the bounded decay; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a decay or spring no maker produced, a NaN bound, a lower bound above the upper, a lower bound of infinity or an upper of -infinity.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnSampleBoundedDecay(const mtwnBoundedDecay* bounded, double position, double velocity, double seconds, double* positionOut, double* velocityOut);
Samples a bounded decay from a start.
Parameters:
bounded: A bounded decay made by this library.position: The start's position, finite.velocity: The start's velocity, per second, finite.seconds: The time since the start, at least 0; infinity gives the rest.positionOut: Receives the position then; may be NULL; unchanged on failure.velocityOut: Receives the velocity then; may be NULL; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null bounded decay, one no maker produced, or a start or time outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeBoundedDecayStopTime( const mtwnBoundedDecay* bounded, double position, double velocity, double offsetTolerance, double stopSpeed, double* secondsOut);
Returns the time a bounded decay from a start comes to rest: a coast's stop at the stop speed, or the spring's settling within the offset tolerance of the bound and the stop speed after it takes over (mtwnComputeSpringSettlingTime).
Parameters:
bounded: A bounded decay made by this library.position: The start's position, finite.velocity: The start's velocity, per second, finite.offsetTolerance: How far from the bound the spring is at rest, above 0.stopSpeed: The speed counted as stopped, per second, above 0.secondsOut: Receives the seconds from the start; infinity for an undamped spring. Unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a bounded decay no maker produced, or a start or tolerance outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnApplyRubberBand(double distance, double dimension, double coefficient, double* offsetOut);
iOS's rubber band: how far content moves when dragged a distance past a limit, in a dimension (the view's size along the drag): c x d / (c x + d), with slope c at the limit, never reaching d. Signed: a negative distance moves the other way.
Parameters:
distance: The drag past the limit, not NaN; may be infinite.dimension: The view's size along it, above 0; may be infinite.coefficient: c, 0.55 on iOS; above 0, and may be infinite.offsetOut: Receives the distance moved; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null offsetOut or an argument outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnInvertRubberBand(double offset, double dimension, double coefficient, double* dragOut);
The inverse of mtwnApplyRubberBand: the drag that moves content an offset past a limit, d o / (c (d - o)).
Parameters:
offset: The distance moved, signed, not NaN.dimension: The view's size along it, above 0; may be infinite.coefficient: c, 0.55 on iOS; above 0, and may be infinite.dragOut: Receives the drag: infinite, signed, for an offset of at least the dimension; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null dragOut or an argument outside the above.
Thread safety. Safe from any thread.
target.hTargets: one animated value of a fixed kind, holding the host's base value, the current value animations compose over it and its velocity. Animations write targets; the host reads them by id.
MTWN_NODISCARD MTWN_API mtwnResult mtwnCreateTarget(mtwnContext* context, mtwnValueKind kind, mtwnVec4 value, mtwnTargetId* targetOut);
Makes a target holding a value as its base and current value, at rest. Channels past the kind's are stored as 0.
Parameters:
context: The context.kind: The kind.value: The value: finite in the kind's channels, for a rotation not all zero, for a scale above 0. Stored as given.targetOut: Receives the target's id, or the null id on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument, an unknown kind or a value outside the above; mtwn_errorCapacity when the context holds its capacity of targets.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnDestroyTarget(mtwnContext* context, mtwnTargetId target);
Destroys a target; its id and every copy of it become stale.
Parameters:
context: The context.target: The target.Returns: mtwn_success; mtwn_errorInvalid for a null context; mtwn_errorStale for an id that names no live target.
Thread safety. Safe from any thread; the context is used by one thread at a time.
bool mtwnTarget_IsValid(const mtwnContext* context, mtwnTargetId target);
Tells whether an id names a live target. Not counted as misuse.
Parameters:
context: The context, or NULL.target: The id.Returns: Whether the target is alive.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnTarget_SetBase(mtwnContext* context, mtwnTargetId target, mtwnVec4 value);
Sets a target's base value, the value animations compose over. A target no animation writes shows it at once; the next update reports the target as changed.
Parameters:
context: The context.target: The target.value: The value, as for mtwnCreateTarget.Returns: mtwn_success; mtwn_errorInvalid for a null context or a value its kind refuses; mtwn_errorStale for an id that names no live target.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnTarget_GetValue(const mtwnContext* context, mtwnTargetId target, mtwnVec4* valueOut);
Reads a target's current value.
Parameters:
context: The context.target: The target.valueOut: Receives the value, zero on failure but mtwn_errorBusy, which leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null argument; mtwn_errorStale for an id that names no live target; mtwn_errorBusy when called from the host's code while the update's clip players run on its task system, which may be writing what the call reads.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnTarget_GetState(const mtwnContext* context, mtwnTargetId target, mtwnTargetState* stateOut);
Reads all of a target: kind, base value, current value and velocity. The velocity may sample the easing writing the target, a host's too, so unlike the other readers it marks the context busy as the calls that change it do: the host's code it runs calling back in is refused, and so is this call made from the host's code the context runs, which could run that code again.
Parameters:
context: The context.target: The target.stateOut: Receives the state, zero on failure but a call back in (mtwn_errorBusy), which leaves it.Returns: As mtwnTarget_GetValue; mtwn_errorBusy for any call back in from the host's code the context runs.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_ReadTargets(const mtwnContext* context, const mtwnTargetId* targets, uint32_t count, mtwnVec4* valuesOut);
Reads many targets' current values, in the order of their ids.
Parameters:
context: The context.targets: The ids; NULL only with a count of 0.count: How many.valuesOut: Receives count values, zero for an id that names no live target. On the other failures, count zeros, without a context too; mtwn_errorBusy leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null argument; mtwn_errorStale when any id names no live target, each such id counted as misuse, the others read; mtwn_errorBusy when called from the host's code while the update's clip players run on its task system, which may be writing what the call reads.
Thread safety. Safe from any thread; the context is used by one thread at a time.
timing.hTiming: Web Animations Level 1's calculation of a node's phase, iteration and progress from its local time, with Level 2's effect playback rate, a repeat delay between iterations and a choice of how reverse iterations ease. Staggers: offsets for items in a grid by their distance from an origin.
mtwnTiming mtwnDefaultTiming(void);
Returns Web Animations' default timing: no delays, fill none, one iteration from 0, a duration of 0, normal direction, linear easing, no repeat delay, time running back in reverse iterations, rate 1.
Returns: The timing.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnValidateTiming(const mtwnTiming* timing);
Checks a timing: delays finite, iteration start finite and from 0, iterations and duration from 0 (infinity allowed, NaN not), repeat delay finite and from 0, playback rate finite and not 0, every enumeration known. The active duration and the end time (delay plus active duration plus end delay) must be finite, unless the iterations or the duration are infinite, making the active duration infinite, and the rate is positive: a backward play starts from the active interval's end, and finite fields that overflow a double there are refused. With a repeat delay, the duration plus the repeat delay must be finite.
Parameters:
timing: The timing.Returns: mtwn_success; mtwn_errorInvalid for a null pointer or a timing outside the above.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeTiming(const mtwnTiming* timing, double localTime, bool backwards, mtwnTimingResult* resultOut);
Computes a node's timing at a local time, by Web Animations' steps.
Parameters:
timing: A timing mtwnValidateTiming accepts.localTime: The node's local time, seconds, finite or positive infinity: the limit, where a finite active interval lies behind and an endless one is still active, an infinite duration's progress at its iteration start (a child of a reversed endless timeline is there).backwards: Whether the time is running backwards (the playing animation's rate is negative), which moves the active interval's boundaries.resultOut: Receives the result; unchanged on failure.Returns: mtwn_success; mtwn_errorInvalid for a null pointer, a timing mtwnValidateTiming refuses, or a local time that is NaN or negative infinity.
Thread safety. Safe from any thread.
mtwnStagger mtwnDefaultStagger(void);
Returns the default stagger: from the first item, 0.1 between neighbors in one row, from 0, linear, both axes.
Returns: The stagger.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnComputeStagger(const mtwnStagger* stagger, uint32_t count, double* offsetsOut);
Computes a stagger's offsets. Item i sits in column i mod columns and row i / columns; its distance d from the origin is Euclidean, or along one axis, or to the nearest edge; t = (d - min) / (max - min), 0 when all are equal, and the offset is start + span * ease(t), where span is the spacing for mtwn_staggerAmount and the spacing times (max - min) for mtwn_staggerEach. A negative span gives start - span * ease(1 - t), as GSAP's distribute does: the farthest items at the start, the nearest at start - span, no offset below the start. The offsets are the same bits on every platform.
Parameters:
stagger: The stagger; its easing made by this library.count: The items; 0 writes nothing.offsetsOut: Receives count offsets, every one finite; unchanged on failure: the easing is sampled at every item before an offset is written, so only a host function giving a value not finite when sampled again there, which is refused too, leaves them unspecified.Returns: mtwn_success; mtwn_errorInvalid for a null pointer with a count, an unknown origin, axis or spacing, an index not below a count above 0 for mtwn_staggerIndex, a start or spacing not finite, a point beyond 2^20, a spread (the spacing, or for mtwn_staggerEach the spacing times the distances' range) not finite, or an offset not finite (the start plus the spread times the eased distance past the doubles, or a host easing's value not finite), writing nothing.
Thread safety. Safe from any thread.
transition.hTransitions: the short path, one call that animates a target from its current value to another. A new transition on a target replaces the one running there, starting from the value it had reached.
static inline mtwnTransitionDef mtwnDefaultTransitionDef(void);
Makes a transition def: no target, an easing over 0.25 seconds, no delay, CSS's ease; for a spring, a critical one of 0.5 seconds' perceptual duration; for a decay, iOS's normal deceleration, 0.998 kept a millisecond; rest within 1e-3 and 1e-2 a second; the target's velocity; colors in Oklab with the shorter hue, angles the shorter way, rotations the shortest.
Returns: The def.
Thread safety. Safe from any thread.
MTWN_NODISCARD MTWN_API mtwnResult mtwnStartTransition(mtwnContext* context, const mtwnTransitionDef* def, mtwnPlayerId* playerOut);
Starts a transition: from the target's current value, at the next update, to the def's value. It replaces the transition running on the target, whose id goes stale. During the delay the start holds at rest. A spring or decay starts with the start velocity: on numbers, vectors, angles and integers per channel, with the spring's or decay's own velocity; colors and rotations spring their path's progress, the start velocity projected on the end minus the start; a scale springs its mix's progress, so it overshoots by a ratio, and decays in its logarithm, its start velocity a share of its value. An angle's end moves by the method's whole turns when started. At its end, a spring's settling time or a decay's stop, the end value (a decay's: where it stopped, a bounded one's bound when it reached one, a landing's value) becomes the target's base value, its velocity 0, and the transition is freed; an undamped spring runs until replaced or stopped.
Parameters:
context: The context.def: The def.playerOut: Receives the transition's player id, or the null id on failure.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a def without its cookie, an end value the target's kind refuses, a delay, duration, given velocity or rest tolerance outside the above, a spring or decay not made by this library, an unknown kind, velocity source, color space, hue method, angle method or rotation path (each whatever the target's kind, one that does not read it too), a color with alpha outside 0 to 1, the longest way between equal rotations, a spring or decay for a discrete value, a decay for a color or rotation, a scale's decay stopping where a float is 0 or infinite, a decay both bounded and landing, a lower bound above the upper or NaN, a scale's bound not above 0, a landing whose velocity does not move a channel toward its value, an easing no maker produced, or linear() points the host changed from the order its maker left them in (not finite, or an input below one before it); mtwn_errorStale for a target that is not alive; mtwn_errorCapacity when the context holds its capacity of players, or for a linear() easing of more points than the context's pointsPerTransition. A linear() easing's points are copied into the context: the host's may change or go once it starts.
Thread safety. Safe from any thread; the context is used by one thread at a time.
MTWN_NODISCARD MTWN_API mtwnResult mtwnContext_MeasureTransition(const mtwnContext* context, const mtwnTransitionDef* def, double* distanceOut);
Measures how far a transition would move its target: from the target's current value to the def's value, in the kind's own measure, for a duration set by speed: def.duration = distance / speed, within whatever bounds the host keeps. Numbers, vectors and integers: their Euclidean distance; an angle: the radians it turns after the method's whole turns; a rotation: the angle it turns on its path; a scale: |ln(to / from)|; a color: Oklab's Euclidean distance (CSS Color 4's deltaEOK) with alpha as a fourth coordinate. Nothing is started or changed.
Parameters:
context: The context.def: The def: its target, value, angle method and rotation path are read.distanceOut: Receives the distance, 0 on failure but mtwn_errorBusy, which leaves it.Returns: mtwn_success; mtwn_errorInvalid for a null argument, a def without its cookie, an end value the target's kind refuses, an unknown angle method or rotation path (whatever the target's kind), the longest way between equal rotations, or a discrete value, which has no distance; mtwn_errorStale for a target that is not alive; mtwn_errorBusy when called from the host's code while the update's clip players run on its task system, which may be writing what the call reads.
Thread safety. Safe from any thread; the context is used by one thread at a time.