Transition
Transition is a lightweight animation helper for one common visual property on one child.
Use it when a state change should ease visually instead of snapping immediately. Typical cases are fading content in, sliding a panel slightly, scaling a pressed card, or rotating a small affordance. It is deliberately smaller than a full animation system. You give it a stable id, a target value, a property, and timing information. The runtime then animates from the current visible value to the new one.
This fits Fission's architecture well because the animation target still comes from explicit state. Your reducer decides that show_banner is now true. build() then describes the banner with a new opacity or translation value. Transition requests the runtime animation, but it does not invent hidden product state of its own.
Example
use fission::core::{AnimationPropertyId, WidgetNodeId};
use fission::prelude::*;
let banner = Transition {
id: WidgetNodeId::explicit("save_banner"),
property: AnimationPropertyId::Opacity,
value: if view.state.show_saved_banner { 1.0 } else { 0.0 },
duration: 250,
delay: 0,
child: Box::new(saved_banner.build(ctx, view)),
}
.build(ctx, view);
Field table
| Field | Type | Meaning | Notes / default behavior |
|---|---|---|---|
id | WidgetNodeId | Stable animation target identity. | Required. Reuse the same id across rebuilds so the runtime can animate from the current visual state. |
value | f32 | Target value for the chosen property. | Defaults to 0.0. Interpret it according to property. |
property | AnimationPropertyId | Which visual property to animate. | Defaults to Opacity. |
duration | u64 | Animation duration in milliseconds. | Defaults to 300. |
delay | u64 | Delay before the animation starts, in milliseconds. | Defaults to 0. |
child | Box<Node> | Content that should visually transition. | Required. The widget wraps it in a repaint boundary for the built-in properties. |
When to use it and when not to
Transition is the right tool when you want one straightforward, state-driven animation on a subtree. It is not the right tool for choreographed multi-element sequences, physics-driven motion, or route-to-route shared element behavior. Those cases usually want a more intentional animation structure such as Hero, nested transitions, or a custom runtime animation strategy.
Specific advice
Keep the id stable and meaningful. If you generate a new id every rebuild, the runtime has no previous visual state to animate from.
Also know the current limits of this helper. The built-in widget applies compositor-friendly wrappers for Opacity, TranslateX, TranslateY, Scale, and Rotation. If you pass AnimationPropertyId::Custom(_), the current implementation leaves the child visually unchanged, so use a lower-level path for truly custom animated properties.
Related
Hero, Composite, and Rendering pipeline.