Skip to main content

Module keyframes

Module keyframes 

Source
Expand description

Keyframes: CSS @keyframes for a node’s animatable slots.

A node with NodeSpec::keyframes cycles those slots through the stops over its transition’s duration, in the transition’s repeat direction, held back by its delay_ms: CSS’s animation-* family on a kui node.

use kui_core::{Color, Keyframe, NodeSpec};

// A pulse: the background goes to red at the middle of each cycle and
// back to the node's own `bg` at the ends.
let pulse = NodeSpec::row()
    .size(40.0, 40.0)
    .bg(Color::hex(0x3b5bd4ff))
    .keyframes(vec![Keyframe::default().at(0.5).bg(Color::hex(0xd43b3bff))])
    .transition(800.0);
assert_eq!(pulse.anim().keyframes.len(), 1);

The rules are CSS’s (and the Web Animations API’s) where they had one: a stop’s at is optional and missing ones spread evenly between their neighbours (the last defaults to 1, the first to 0; a lone stop is the far end and animates from the node’s own value); a slot a stop leaves out is not part of that stop; and a slot whose stops do not reach 0 or 1 gets the node’s own declared value there.

Stops arrive as plain data from the bindings (parse), and the runtime flattens them per slot into the tracks the animation store samples each frame.

Structs§

Keyframe
One stop. Every field is optional: at resolves by position, and a slot a stop doesn’t name is left to its neighbours. Derefs to its Slots, so stop.bg reads the slot.

Functions§

offsets
Every stop’s position: declared ats kept, the rest spread evenly between the nearest declared neighbours (0 and 1 at the ends).
parse
Stops from plain data: a list of maps with any of at, width, height, bg, radius, opacity, in the forms the props themselves take (sizings as a number, "grow", "50%", {grow} / {percent}; colors as 0xRRGGBBAA or "#hex"). Every binding funnels its keyframes through here, so the shape is the same in JSX, Lua and C.
parse_with
parse with a token lookup: a $name in a stop’s width, height, bg or radius resolves through refs, and one that misses leaves that slot unnamed and is remembered on the refs for the binding to raise. Without refs a $name is an error, since there is nothing to resolve it against.