Skip to content

Animations

An animate block attaches an animation to a property. Whenever that property’s value changes, the value moves to its target over time rather than jumping to it at once:

export component Example inherits Window {
background: area.pressed ? blue : red;
animate background {
duration: 250ms;
}
area := TouchArea {}
}
slint

An animate block is a statement inside an element’s body. It may appear on any element — the root, a child, or a sub-component’s root. A global may not contain an animate block; doing so is a compile error.

The animate keyword is followed by one or more property names and a brace-delimited body of bindings:

animate <property> {
// field: value;
}
slint
  • Each name refers to a property of the element the animate block sits on. A qualified name such as other.property is not allowed here; it is a compile error to refer to a property of another element.
  • The body may contain only bindings of the form field: value;. Any other statement is a compile error.
  • The only fields are delay, duration, easing, iteration-count, direction, and enabled. Binding any other name is a compile error. Every field is optional.

Attaching two animate blocks to the same property is a compile error.

A property can be animated only when its type is one of: int, float, length, physical-length, color, brush, or angle. Animating a property of any other type — for example a string, bool, image, or struct property — is a compile error.

The property must also be settable on the element. Animating a property that cannot be assigned, such as a private property of another component, is a compile error.

Listing several comma-separated names applies the same animation to each:

animate x, y { duration: 100ms; easing: ease-out-bounce; }
slint

is equivalent to:

animate x { duration: 100ms; easing: ease-out-bounce; }
animate y { duration: 100ms; easing: ease-out-bounce; }
slint

Each named property must be animatable and settable, subject to the rules above.

durationdefault: 0ms

The amount of time to wait before the animation starts.

durationdefault: 0ms

The amount of time the animation takes to complete.

floatdefault: 1

The number of times the animation runs. A negative value runs it forever. Fractional values are allowed. For a continuously running value independent of property changes, see `animation-tick()`.

easingdefault: linear

The easing curve applied over the animation’s duration. See easings.net for a visual reference.

enum AnimationDirectiondefault: the first enum value

The direction in which each iteration plays.

AnimationDirection

This enum describes the direction of an animation.

booldefault: true

Whether the animation runs. When false, a change sets the property to its target value at once, with no delay, easing, or iteration.

Inside a transition an animate block instead describes how the property moves when the state changes. There a name may be qualified, as in animate root.background { ... }, so a transition can animate properties of nested elements. The fields are the same as above. See States and Transitions for where transitions are written and how they select which animation applies.

The spring easing curve takes an optional bounce argument, for example spring(0.4). The bounce must be a number literal between -1 and 1; any other argument is a compile error. Writing just spring is the same as spring(0).

Since duration helps define the spring’s natural frequency, the animation is not guaranteed to be done after duration elapses. If bounce is close to 0, the animation will be nearly done, however the further from 0 bounce is, the longer the animation will take.

A spring with a finite iteration-count cannot oscillate forever. It is clamped to at most (iteration-count + 9) x duration in total. When iteration-count is set to -1, this clamp never applies. Every iteration up to iteration-count runs at bounce. If the spring hasn’t settled by the end of the final iteration’s duration, it’s re-damped so it settles within a further 9x duration (10x duration in total from the start of the last iteration).

An iteration-count of -1 makes the animation infinite, and a bounce of 1 makes the loop seamless. See Iterations and Directions below for why.

Unlike other easing curves, springs maintain velocity on retarget, so it keeps moving smoothly instead of jumping to a new curve.

  • bounce = 0: the value approaches the target as quickly as possible without overshooting it (critically damped).
  • bounce > 0: the value approaches the target quickly but overshoots it (underdamped) — the closer to 1, the longer it takes to settle.
  • bounce < 0: the value approaches the target slowly without overshooting it (overdamped).
export component Example inherits Window {
width: 200px;
height: 100px;
ball := Rectangle {
x: area.pressed ? 150px : 0px;
width: 50px;
height: 50px;
border-radius: 25px;
background: blue;
animate x {
duration: 500ms;
easing: spring(0.5);
}
}
area := TouchArea {}
}
slint

The spring’s animation relies on the natural frequency(ω₀ = 2π/duration) and the damping ratio(ζ = 1 - bounce) to feed the mass-spring-damper model.

Because a spring is not guaranteed to settle by duration, a repeating spring animation (iteration-count greater than 1) moves on to its next iteration at exactly duration, rather than waiting for the spring to fully settle.

The spring’s velocity always carries over into the next iteration. What happens to its position depends on whether that iteration also flips direction:

  • A same-direction repeat resets the position to the start of the animation, the same way a repeating easing-curve animation restarts from the top.
  • A direction flip (alternate or alternate-reverse) instead continues from wherever the spring actually is, so the value keeps moving smoothly instead of snapping to the far end.

If bounce is set to 1, the period of the spring is exactly duration. If an object is animated from x = 0px to x = 100px, this results in x == 0px at exactly duration. Since the next iteration starts at exactly duration, as long as direction is not alternate or alternate-reverse, an iteration-count of -1 will be an infinite continuous spring. If bounce is set to values other than 1, the position will not quite be at either end of the animation and there will be a noticeable jump.


© 2026 SixtyFPS GmbH