You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/arts/motion/README.md

4.2 KiB

motion — animation runtime

EngineMotion is the runtime engine for the UIX motion system: it registers motion presets and runs them. It is an art (a pure runtime artifact, public methods over private state, no reactive $state) so that both UIX layers can consume it via uix.motion without a cross-layer dependency:

  • soma (Presence) calls motion.run(node, phase) to run + await a JS preset (a spring) before unmounting — the gating soma can't get from getAnimations() alone.
  • eidos generates the CSS (keyframes + preset rules), registers its visual presets into the engine, and drives wrappers.

The engine owns the execution; eidos owns the CSS generation and the visual presets data. Neither imports the other — they meet at uix.motion.

The two moments

Motion occurs in two moments, each animable (one, the other, or both):

--event --state
Attr data-event-* (sema) data-state (soma)
What the perceptual firma during a signal's hold the transition to/from a persistent condition
Registry signatures (eidos generates CSS) presets (named, per-component)

EngineMotion runs the --state presets (CSS → settled; JS → driver). The --event firma is CSS that eidos generates from signatures; the engine does not run it.

API

const motion = createEngineMotion({ dom })          // dom: a MotionDom port

motion.register('scale-fade', { driver: 'css', … }) // eidos registers presets
motion.register('pop', { driver: 'spring', enter: spring({ … }) })

motion.run(node, 'enter')        // resolve node's data-animation-style + run
motion.enter(el, 'pop')          // run a preset by name (enter phase)
motion.exit(el, 'pop')           // run a preset by name (exit phase)
motion.cancel(el)                // cancel active JS motion on el
await motion.pending(el)         // combined finished, for Presence
motion.dispose()                 // idempotent: cancel all + clear registry

// registry introspection
motion.has('pop')                // is a preset registered?
motion.resolve('pop')            // the StatePreset, or undefined
motion.list()                    // registered preset names
  • CSS preset → declarative: a settled handle (the generated CSS + soma's Presence via getAnimations() do the work).
  • JS preset → runs its MotionRun driver, normalises the result (Animation | Animation[] | MotionHandle) to one handle, tracks it per element. pending(el) is what Presence awaits for drivers (spring) that getAnimations() can't see.

Drivers (./drivers)

MotionRun factories for JS presets:

  • spring — self-contained physics: an independent semi-implicit-Euler spring per property, stepped via ctx.dom.requestFrame. Overshoot + settle — the curve no cubic-bezier expresses. Cancellable via ctx.signal.
  • waapi — el.animate(...). The Animation is in getAnimations(), so Presence awaits it for free.
  • rect — FLIP: measures first/last rects, animates the inverse delta via WAAPI (layout / shared-element transitions).

JsDriver also declares 'svelte', but it is reserved / not yet implemented — no driver dispatches it. The three drivers above are the whole set today.

The DOM port

This art imports no other art. The DOM dependency arrives injected and is typed by the structural MotionDom port (requestFrame / cancelFrame / prefersReducedMotion); the real ActiveDom satisfies it.

Composition

// active-app (attach path)
const App = createActiveApp({
	services: { dom: defineActiveDom(), motion: defineEngineMotion() }
});

// active-uix (standalone) creates it directly and exposes uix.motion.

Without a dom service the engine degrades (JS drivers settle; CSS is declarative regardless). duration / ease are string (token keys or raw values); eidos validates the keys — this art stays token-agnostic.

Powered by TurnKey Linux.