Skip to content

动画

animate 块将动画附加到某个属性。 每当该属性的值发生变化时,值会随时间移动到其目标值,而不是立即跳变过去:

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

animate 块是元素体内的语句。 它可以出现在任何元素上——根元素、子元素或子组件的根元素。 全局对象不得包含 animate 块;这样做会构成编译错误。

animate 关键字后跟一个或多个属性名,以及一个由花括号界定、包含若干绑定的主体:

animate <property> {
// field: value;
}
slint
  • 每个名字都指向 animate 块所在元素的一个属性。 此处不允许使用诸如 other.property 这样的限定名;引用另一个元素的属性会构成编译错误。
  • 主体中只能包含 field: value; 形式的绑定。 任何其他语句都会构成编译错误。
  • 仅有的字段为 delay、duration、easing、iteration-count、direction 和 enabled。 绑定任何其他名字都会构成编译错误。 每个字段都是可选的。

将两个 animate 块附加到同一个属性会构成编译错误。

只有当属性的类型为以下之一时,才可以对其应用动画: int、float、length、physical-length、color、brush 或 angle。 对任何其他类型的属性应用动画——例如 string、bool、image 或结构体属性——都会构成编译错误。

该属性还必须是可在该元素上设置的。 对无法赋值的属性应用动画(例如另一个组件的私有属性)会构成编译错误。

列出以逗号分隔的多个名字,会对每个名字应用相同的动画:

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

等价于:

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

每个被命名的属性都必须满足上述规则,即可动画且可设置。

durationdefault: 0ms

动画开始前等待的时间。

durationdefault: 0ms

动画完成所需的时间。

floatdefault: 1

动画运行的次数。负值会使其永远运行。 允许使用小数值。若要获得与属性变化无关、连续运行的值, 请参见 `animation-tick()`。

easingdefault: linear

在动画时长内应用的 缓动曲线。 可视化参考请见 easings.net。

enum AnimationDirectiondefault: the first enum value

每个迭代播放的方向。

booldefault: true

动画是否运行。当为 false 时,变化会立即将属性设置为 目标值,没有延迟、缓动或迭代。

在过渡内部,animate 块则描述状态改变时属性如何移动。 在那里名字可以是限定名,例如 animate root.background { ... },因此过渡可以为嵌套元素的属性应用动画。 字段与上文相同。 关于过渡的书写位置以及它们如何选择应用哪个动画,请参见状态与过渡。

spring 缓动曲线接受一个可选的 bounce 参数,例如 spring(0.4)。 bounce 必须是介于 -1 和 1 之间的数字字面量;任何其他参数都会构成编译错误。 只写 spring 与 spring(0) 相同。

由于 duration 有助于定义弹簧的固有频率,动画并不保证在 duration 流逝后完成。 如果 bounce 接近 0,动画将接近完成;然而 bounce 离 0 越远,动画所需的时间就越长。

具有有限 iteration-count 的弹簧无法永远振荡。它的总时长最多被限制为(iteration-count + 9)x duration。 当 iteration-count 设为 -1 时,该限制永远不适用。 直到 iteration-count 的每一次迭代都以 bounce 运行。 如果弹簧在最后一次迭代的 duration 结束时仍未稳定,它会被重新阻尼,使其在额外的 9x duration 内稳定(从最后一次迭代开始算起总计 10x duration)。

iteration-count 为 -1 会使动画无限进行,bounce 为 1 会使循环无缝衔接。 原因请见下方的 迭代与方向。

与其他缓动曲线不同,弹簧在重新定向时会保持速度,因此它会平滑地继续移动,而不是跳变到一条新曲线上。

  • bounce = 0:值尽可能快地接近目标而不越过它(临界阻尼)。
  • bounce > 0:值快速接近目标但会越过它(欠阻尼)——越接近 1,稳定所需的时间越长。
  • bounce < 0:值缓慢接近目标而不越过它(过阻尼)。
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

弹簧动画依赖固有频率(ω₀ = 2π/duration)和 阻尼比(ζ = 1 - bounce)来驱动质量-弹簧-阻尼器模型。

由于弹簧不保证在 duration 内稳定,重复的弹簧动画 (iteration-count 大于 1)会在恰好 duration 时进入下一次迭代,而不是 等待弹簧完全稳定。

弹簧的速度总会延续到下一次迭代。其位置会怎样 取决于该次迭代是否也翻转了方向:

  • 同方向重复会将位置重置到动画的起点,就像 重复的缓动曲线动画从头重新开始一样。
  • 方向翻转(alternate 或 alternate-reverse)则会从弹簧 实际所在的位置继续,因此值会平滑地继续移动,而不是突然跳到另一端。

如果 bounce 设为 1,弹簧的周期恰好为 duration。如果将一个对象从 x = 0px 动画到 x = 100px, 那么在恰好 duration 时会有 x == 0px。由于下一次迭代恰好从 duration 开始,只要 direction 不是 alternate 或 alternate-reverse,iteration-count 为 -1 就会形成无限连续弹簧。如果 bounce 设为 除 1 以外的值,位置就不会恰好位于动画的两端,并且会出现明显的跳变。


© 2026 SixtyFPS GmbH