Appear

Appear animations: a mount animation a server renders as CSS, played from the first paint, before any code runs, which the engine takes over at mount from where it has got to. The DOM's half, for any binding:

  • On a server: keyframes samples an element's spec, its mount animation built with core's machines, into one @keyframes rule, cached across requests. A render's sheet gives each element a slot, whose animation goes in its inline style, and writes the head's <style> once every slot's timing is defined.
  • At mount: find the element's animation, check it matches the client's own spec, start the run elapsedOf it in (Machine.startAt), and release the element in the task that writes the engine's first frame.
import * as Appear from "@wardic/dom/Appear"

// On a server, a sheet a render:
const render = Appear.sheet()
const slot = render.slot()
slot.define({ spec, delay: 0 }) // `slot.animation` goes in the element's style, `render.css()` in the head
// At mount:
const elapsed = Option.map(Appear.find(element), Appear.elapsedOf)

Interfaces

Keyframes

A spec's @keyframes rule.

Properties

css
readonly css: string;

The rule, @keyframes <name>{…}.

duration
readonly duration: number;

Seconds the rule plays, a multiple of 1/60 s: to the first Frame from which every one is within tolerance of the settled one.

infinite
readonly infinite: boolean;

Whether it plays over and over.

name
readonly name: string;

The rule's name: wardic- and the spec's hash.

settled
readonly settled: number;

Seconds to the Frame the spec settles at, which a client waits for: at or past duration.

supports
readonly supports: readonly string[];

The SVG geometry properties its stops write (cx, r…), which some browsers don't draw from CSS: an element playing it is defined under @supports for each, so a browser without them keeps it at its starting style. Empty for most rules.

times
readonly times: readonly number[];

The time of each stop kept, in seconds from the start.


Play

Where an element's timing is decided: a spec, and the delay it starts after.

Properties

delay
readonly delay: number;

Seconds before it starts: its orchestration's, and any delay on the whole element.

spec
readonly spec: Spec;

The element's mount animation.


Sheet

One render's Appear rules: a slot per element, and the <style> text for the head and each late chunk.

Properties

css
readonly css: () => string;

The CSS since the last call: each rule this render hasn't written yet, and the custom property of each slot defined since, the reduced ones under the media query. Called once for the head, and again for each chunk a stream sends after its shell, with only what that chunk adds.

Returns

string

slot
readonly slot: () => Slot;

A slot for the next element.

Returns

Slot


Slot

One element's place in a sheet.

Properties

animation
readonly animation: string;

The element's inline animation: var(--wardic-aN), which the sheet defines once define is called.

define
readonly define: (play, reduced?, supports?) => Result<void, string>;

The element's timing: play, and under prefers-reduced-motion: reduce reduced when given (a provider's "user"). Undefined until called, and left so when either spec has no rule: the element keeps its Starting style. The reason comes back for the debug log.

Defined under @supports for the geometry properties its rules write and supports: a binding passes the ones every element it orchestrates with writes, so a browser without them keeps the whole group at its starting style, not half of it.

Parameters
play

Play

reduced?

Play

supports?

readonly string[]

Returns

Result<void, string>


Spec

An element's mount animation, as its binding describes it.

Properties

infinite?
readonly infinite?: boolean;

Played over and over: an infinite repeat, machine one cycle of it.

key
readonly key: string;

What built the animation, as one string the binding writes the same on the server and the client: its starting values, its targets, its transition, whether motion is reduced. The rule's name is its hash, so a client tells a Handoff it can continue from one it can't (decision 6).

machine
readonly machine: LazyArg<Machine<Frame<Values>>>;

The animation's values from its start (for an infinite one, one cycle of it), built only when the rule isn't cached: a server render calls it once per spec per process.

projected?
readonly projected?: boolean;

A layout node: drawn through its projection at rest, as the client draws it, its own move on top.

tag
readonly tag: string | undefined;

The element's tag, so an SVG element's keys go to its attributes; undefined for an HTML element.

template?
readonly template?: TransformTemplate;

The element's transform template: each stop's transform drawn through it, as the client draws it. A function's text can't name a rule, so a templated spec's rule is named by its stops, and sampled for each element that has one, never cached.

Variables

CHUNK_ATTRIBUTE

const CHUNK_ATTRIBUTE: "data-wardic-appear-chunk" = "data-wardic-appear-chunk";

The attribute a late chunk's <style> carries: a chunk a stream sends after its shell brings its own rules, in a node its client doesn't render.


MAX_SECONDS

const MAX_SECONDS: 60 = 60;

The longest mount animation sampled, in seconds; a longer one keeps its Starting style.


PREFIX

const PREFIX: "wardic-" = "wardic-";

The prefix every Appear rule's name starts with.

Functions

adoptChunks()

function adoptChunks(doc): void;

Moves each late chunk's Appear rules into the head: its <style data-wardic-appear-chunk>'s text into a head <style>, then the node out, before the chunk hydrates, since a hydrating client expects no node it doesn't render. The text goes first, so the rule a running animation plays is never missing. Chunks already in the document move at once; while it's still loading, a stream still coming, a MutationObserver moves each as it lands, until DOMContentLoaded. Every call moves what's there; one observer a document.

Parameters

doc

Document

Returns

void


animationOf()

function animationOf(rule, delay): string;

An element's animation value for a play of rule: its name, length, delay and repeat, filling forwards. Not backwards: through its delay the element shows its inline starting style, which is the rule's first stop for a rule that moves from it.

Parameters

rule

Keyframes

delay

number

Returns

string


chunkStyle()

function chunkStyle(css, nonce?): string;

A late chunk's <style> for css, as server text; "" for none. With a nonce, the one the page's Content Security Policy gives inline styles, it carries it.

Parameters

css

string

nonce?

string

Returns

string


delayOf()

function delayOf(animation): number;

The delay animation started after, in seconds: what its element's animation-delay holds.

Parameters

animation

Animation

Returns

number


elapsedOf()

function elapsedOf(animation): number;

How far animation has got, in seconds since it started (its delay included): 0 before it has.

Parameters

animation

Animation

Returns

number


find()

function find(element): Option<Animation>;

The element's Appear animation: its wardic-… CSS animation, running, or finished and filling.

Parameters

element

Element

Returns

Option<Animation>


keyframes()

function keyframes(spec): Result<Keyframes, string>;

A spec's rule, or why it has none, for a debug log. Sampled once a spec and cached across requests by its name, since a spec's rule changes only once the page registers every colour space (Color.registerSpaces): a wide-gamut colour blends as written before, in sRGB after. Its name stays, so a client matches it whatever it had registered. A templated spec's is sampled each time: its name comes from its stops.

Parameters

spec

Spec

Returns

Result<Keyframes, string>


matches()

function matches(animation, spec): boolean;

Whether animation is spec's: the rule the server sampled from the same spec.

Parameters

animation

Animation

spec

Pick<Spec, "key" | "tag" | "infinite" | "projected">

Returns

boolean


nameOf()

function nameOf(spec): string;

The rule's name for a spec: its key, tag, repeat and projection, hashed.

Parameters

spec

Pick<Spec, "key" | "tag" | "infinite" | "projected">

Returns

string


pending()

function pending(element): boolean;

Whether element's Appear animation is running, not yet handed over: its inline style still names its slot, which release removes. A layout measure asks it of each node, so a running animation's transform, which beats the inline one, stays out of the box it reads.

Parameters

element

ElementCSSInlineStyle

Returns

boolean


release()

function release(element): void;

The handover's last step: the element's inline animation removed, in the task that writes the engine's first frame, so no paint falls between. While it ran, its value beat the inline style the engine writes; removing it ends the CSS animation at that task's style update.

Parameters

element

ElementCSSInlineStyle

Returns

void


sheet()

function sheet(): Sheet;

A sheet for one render: a slot per element, and the CSS for the head.

Returns

Sheet