Using Animations / 使用动画

PixelUI 对动画的定义是“在一段时间内把 int32_t 从 A 改到 B”。

在底层用定点数计算 easing,动画对象直接存在固定容量的 AnimationManager 里。

Animation demo

API 介绍

  • PixelUI内置了三种便捷的API,他们分别针对只需要一个变量的动画、只需要两个变量的动画以及需要自定义回调的动画。

单值动画

1
2
3
4
5
6
int32_t panelX = -64;

if (!ui.animate(panelX, 0, 400, EasingType::EASE_OUT_CUBIC)) {
// 动画容器已满
panelX = 0;
}

animate() 返回值是 bool类型。当 PIXELUI_MAX_ANIMATION_COUNT 个位置已经用完时,它将返回 false

两个值的动画

1
2
3
4
if (!ui.animate(x, y, 32, 20, 500, EasingType::EASE_IN_OUT_QUAD)) {
x = 32;
y = 20;
}

这个重载需要同时有两个空动画位,否则直接失败,不会只启动 X 或 Y 其中一个。

使用动画的自定义回调

1
2
3
4
5
6
7
8
ui.animateCallback(
0,
100,
600,
EasingType::EASE_OUT_CUBIC,
[this](int32_t value) {
brightness_ = value;
});

回调会被存进 etl::inplace_function<..., CALLBACK_STORAGE_SIZE> 里,所以会受CALLBACK_STORAGE_SIZE 的限制,捕获太大会导致编译期断言失败。显然,捕获 this 或引用时,目标必须活到动画结束或被清理。容量配置见资源上限

变换函数类型

动画系统支持以下几种变换函数

缓动函数 运动特点
LINEAR 匀速运动,无加速度
EASE_IN_QUAD 慢速启动,二次方加速
EASE_OUT_QUAD 快速启动,二次方减速
EASE_IN_OUT_QUAD 慢速启动,中间加速,慢速减速
EASE_IN_CUBIC 极慢启动,三次方强力加速
EASE_OUT_CUBIC 快速启动,三次方显着减速
EASE_IN_OUT_CUBIC 极慢启动,三次方强力加速后慢速减速
EASE_OUT_BOUNCE 快速到达终点后产生多次弹性反弹

刷新和 markDirty()

为了让系统不做无效渲染,UI框架引入了 dirty 标记机制。

只有系统 dirty 标脏,下一次主循环对 renderer() 的调用才会触发渲染。

AnimationManager 在动画更新的 deadline 到达时更新值并标记 dirty。如果一个app页面中没有任何的动画进行更新,你仍要调用 ui.markDirty()来触发新的一屏渲染。调度规则见事件驱动渲染

保护和清理

  • 你可以给动画标记 PROTECTION::PROTECTED 来阻止它在调用 clearUnprotectedAnimations()(弱动画清理)时被清理。
  • clearAllAnimations() (强清理)会清理全部动画,包括 protected 动画。
  • ViewManager 在 App 切换/退出时会清理全部动画,为保证安全释放资源,保护标志不会让动画跨过已被销毁的 App。
  • clearAnimationProtection() 只取消保护标记,不会立即删除动画。

动画持有变量引用。如果目标不是 App 成员,要格外确认它的寿命。一般只应该对 App 成员使用动画系统。

avatar
Link0327
喵🐱me0w, but furry wolf. 尝试变得毛茸茸
Link's Github