Skip to main content

Module anim

Module anim 

Source
Expand description

Transitions: retained tweens keyed by node identity.

A node that declares NodeSpec::transition has its animatable spec values (sizing amounts, colours, radius, opacity, shadow) eased from whatever they were last frame toward what the view declares this frame. The inputs to layout animate, so a subtree lays out consistently every frame instead of children snapping to a target size inside a still-moving parent. The view keeps declaring the target; nothing else is needed.

use kui_core::{Easing, NodeSpec, Sizing, Transition};

// A sidebar whose width eases over 200 ms, keyed so the tween survives.
let open = true;
let w = if open { 240.0 } else { 48.0 };
let sidebar = NodeSpec::column().width(Sizing::Fixed(w)).transition(200.0);

// A spring instead of a curve, with a little overshoot.
let springy = Transition::ms(350.0).easing(Easing::Spring).bounce(0.3);
let card = NodeSpec::row().transition_with(springy).slide();

assert_eq!(sidebar.transition.unwrap().easing, Easing::EaseOut);
assert!(card.transition.unwrap().curve().is_spring() && card.slide);

Two kinds of motion: timed curves (Easing::EaseOut and friends, which replay a leg from wherever the value was over duration_ms) and springs (Easing::Smooth, Easing::Snappy, Easing::Spring, Easing::Bouncy), integrated per frame with a velocity that survives retargets — a value chased mid-flight keeps its momentum instead of restarting, which is what dragged and reordered things want.

A spring takes the two numbers a person tunes by eye, not the physics: duration_ms, how long it takes to get there (the response time), and a Bounce, how far it overshoots — 0 glides in, 0.5 bounces. Each spring easing is a named bounce, and Transition::bounce sets any other; the stiffness and damping follow from the two.

A node can also declare crate::NodeSpec::keyframes: CSS-style stops for any of the same slots, cycled over duration_ms in one of CSS’s four directions (Repeat). A keyframed slot is sampled straight off the clock instead of retained as a tween, so nothing drifts, siblings offset by delay_ms stay in phase with each other, and a view that declares a pulse never has to wake up to flip a target.

The core stays clock-free: the frame driver injects the time with crate::Core::set_time. A driver that never does (headless tests, a C host without a clock) sees every transition snap to its target.

Structs§

AnimStore
Bounce
How far a spring overshoots, 0 (glides in, no overshoot) to MAX_BOUNCE (rings a while): the one number that shapes a spring besides its duration. A bounce b is a damping ratio of 1 - b (SwiftUI’s Spring(duration:bounce:)).
Transition
How a node’s animatable values move when the view changes them: a duration, an easing (a timed curve or a spring), and for keyframes a repeat direction and a delay. Built with Transition::ms and the builders, or through the NodeSpec shorthands (transition, easing, bounce, repeat, delay).

Enums§

Easing
Easing curve for a Transition.
Repeat
How keyframes cycle: CSS’s animation-direction, always infinite.

Constants§

MAX_BOUNCE
The most bounce a spring takes: at 1 it would never settle, and past 0.9 it rings for seconds.