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§
- Anim
Store - 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 bouncebis a damping ratio of1 - b(SwiftUI’sSpring(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::msand the builders, or through theNodeSpecshorthands (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.