docs/development/animation-internals.md
Note for AI coding assistants (agents): When to load this document: Working on
internal/core/animations.rs, debugging animation timing issues, or optimizing animation performance. For general build commands and project structure, see/AGENTS.md.
Slint animations use a mocked time system rather than real-time clocks. This provides:
The animation driver (internal/core/animations.rs) manages a global instant that advances each frame:
AnimationDriver
├── global_instant: Property<Instant> // Current animation time
├── active_animations: bool // Whether animations are running
└── update_animations(new_tick) // Called per frame by the backend
Key components:
| Function/Type | Location | Purpose |
|---|---|---|
Instant | internal/core/animations.rs | Milliseconds since animation driver started |
current_tick() | internal/core/animations.rs | Get current animation time (registers dependency) |
animation_tick() | internal/core/animations.rs | Same, but signals a frame is needed |
update_timers_and_animations() | internal/core/platform.rs | Called by platform each frame |
EasingCurve | internal/core/items.rs | Enum of easing curve types |
Easing curves are defined in the EasingCurve enum in internal/core/items.rs. The interpolation logic is in internal/core/animations.rs.
For cubic-bezier(a, b, c, d), Slint uses a binary search algorithm to find the t parameter for a given x value, then evaluates the y component of the bezier curve.
Standard easings (ease-in, ease-out, ease-in-out, etc.) are pre-defined cubic bezier curves.
Each animated property:
Efficient to animate (no layout recalculation):
x, y - Positionopacity - Transparencyrotation-angle - Rotationbackground - Colors/gradientsExpensive to animate (triggers layout):
width, heightpreferred-width, preferred-height# Slow animations by factor of 4
SLINT_SLOW_ANIMATIONS=4 cargo run
# Slow by factor of 10 for detailed inspection
SLINT_SLOW_ANIMATIONS=10 cargo run
Useful for:
// In application code
if window.has_active_animations() {
// Animations are in progress
}
For deterministic testing without real-time waits:
use slint_testing::mock_elapsed_time;
// Advance animation time by 100ms
mock_elapsed_time(100);
// Complete a 300ms animation
mock_elapsed_time(300);
This is implemented in internal/core/tests/ and used throughout the test suite.
| File | Purpose |
|---|---|
internal/core/animations.rs | Animation driver, timing, interpolation |
internal/core/items.rs | EasingCurve enum definition |
internal/core/timers.rs | Timer integration with animation system |
internal/core/platform.rs | update_timers_and_animations() entry point |
EasingCurve enum in internal/core/items.rsinternal/core/animations.rsinternal/compiler/ if new syntax neededtests/cases/SLINT_SLOW_ANIMATIONS=10 to slow downanimations.rs) or rendering (renderers/)eprintln! in update_animations() to trace tick values