统一文档标题格式,在以下文档的 H1 标题前添加 AtomUI 前缀: - AnimationSystem.md - CollectionSystem.md - CoreTypesAndUtilities.md - DataBindingSystem.md - MediaAndDrawing.md
9.0 KiB
AtomUI 动画与过渡系统(Animation & Transition System)
概述
动画与过渡系统是 AtomUI 动效体系的底层基础设施,位于 src/AtomUI.Core/Animations/ 目录。它为上层的 MotionScene 动效场景系统 提供了类型安全的属性插值、可通知的过渡动画以及动画生命周期管理能力。
与 MotionScene 关注"何时播放什么动效"不同,本系统关注的是**"如何在两个值之间平滑过渡"**这一核心问题。
在整体架构中的位置
MotionScene(动效场景 — 高层编排)
↓ 使用
Animation & Transition System(本文档 — 底层插值与过渡)
↓ 基于
Avalonia Animation Framework(框架原生动画能力)
目录结构
Animations/
├── AnimationExtensions.cs # 动画循环播放扩展
├── AnimatableReflectionExtensions.cs # Animatable 私有 API 反射访问
├── BaseTransitionUtils.cs # 过渡动画工厂
├── InterpolateUtils.cs # 全类型插值引擎(核心)
└── Transitions/
├── INotifyTransitionCompleted.cs # 完成通知接口
├── AbstractNotifiableTransition.cs # 可通知过渡基类
├── BoxShadowsTransition.cs # 阴影过渡
├── SolidColorBrushTransition.cs # 画刷过渡
├── NotifiableBoolTransition.cs # Bool 过渡
├── NotifiableDoubleTransition.cs # Double 过渡
├── NotifiableFloatTransition.cs # Float 过渡
├── NotifiableIntegerTransition.cs # Int 过渡
├── NotifiablePointTransition.cs # Point 过渡
├── NotifiableRelativePointTransition.cs # RelativePoint 过渡
├── NotifiableSizeTransition.cs # Size 过渡
├── NotifiableThicknessTransition.cs # Thickness 过渡
├── NotifiableVectorTransition.cs # Vector 过渡
├── NotifiableCornerRadiusTransition.cs # CornerRadius 过渡
├── NotifiableBoxShadowsTransition.cs # BoxShadows 可通知过渡
└── NotifiableTransformOperationsTransition.cs # Transform 过渡
核心组件
1. InterpolateUtils — 全类型插值引擎
InterpolateUtils 是整个动画系统的计算核心,提供了覆盖所有 Avalonia 常用类型的静态插值方法。所有过渡类都将实际的数值计算委托给此工具类。
支持的插值类型
| 类型 | 方法 | 说明 |
|---|---|---|
double |
DoubleInterpolate |
线性插值 |
float |
FloatInterpolate |
线性插值 |
int |
IntegerInterpolate |
归一化整数插值 |
bool |
BoolInterpolate |
progress >= 1.0 时切换 |
Point |
PointInterpolate |
二维点向量插值 |
RelativePoint |
PointInterpolate(重载) |
感知单位(像素/百分比)的插值 |
Size |
SizeInterpolate |
宽高插值 |
Thickness |
ThicknessInterpolate |
四边 Margin/Padding 插值 |
Vector |
VectorInterpolate |
二维向量插值 |
CornerRadius |
CornerRadiusInterpolate |
四角圆角独立插值 |
Color |
ColorInterpolate |
预乘 Alpha 颜色混合 |
BoxShadow / BoxShadows |
BoxShadow(s)Interpolate |
多阴影的颜色、模糊、扩散、偏移插值 |
ITransform |
TransformOperationsInterpolate |
变换矩阵插值 |
ISolidColorBrush |
SolidColorBrushInterpolate |
画刷颜色与不透明度插值 |
IGradientBrush |
GradientBrushInterpolate |
线性/径向/锥形渐变插值 |
IBrush |
BrushInterpolate |
自动分发到对应画刷插值器 |
颜色插值的特殊处理
颜色插值使用**预乘 Alpha(Premultiplied Alpha)**算法,确保半透明颜色的混合在视觉上正确:
R_result = R_from * (1 - progress) + R_to * progress
对于接近透明的颜色(Alpha < 1/256),直接采用另一端颜色的 RGB 分量,避免除以零或颜色偏移。
跨类型画刷插值
系统支持 SolidColorBrush 与 GradientBrush 之间的平滑过渡:将纯色画刷自动转换为与目标渐变同结构的渐变画刷(所有 Stop 颜色相同),然后逐 Stop 进行颜色插值。
2. INotifyTransitionCompleted — 完成通知接口
public interface INotifyTransitionCompleted : ITransition
{
IObservable<bool> CompletedObservable { get; }
event EventHandler<TransitionCompletedEventArgs>? TransitionCompleted;
TimeSpan Duration { get; }
}
该接口扩展了 Avalonia 原生的 ITransition,增加了两种完成通知机制:
- 事件(Event):传统的
TransitionCompleted事件 - 响应式流(Observable):
CompletedObservable提供 Rx 风格的订阅
3. AbstractNotifiableTransition<T> — 可通知过渡基类
Avalonia.TransitionBase
└── Avalonia.InterpolatingTransitionBase<T>
└── AbstractNotifiableTransition<T> ← 实现 INotifyTransitionCompleted
└── 12 个具体过渡类型
所有可通知过渡都继承此抽象基类,它封装了:
- 基于
Subject<bool>的响应式完成信号发射 - 使用
MathUtils.AreClose()的浮点容差完成检测(而非精确的progress == 1.0) - 统一的
CheckCompletedStatus+NotifyTransitionCompleted模板
统一的插值模式
每个具体过渡类遵循相同的实现模式:
protected override T Interpolate(double progress, T from, T to)
{
var result = InterpolateUtils.XxxInterpolate(progress, from, to);
if (CheckCompletedStatus(progress))
{
NotifyTransitionCompleted(true);
}
return result;
}
4. BaseTransitionUtils — 过渡工厂
提供泛型工厂方法,简化过渡实例的创建:
public static ITransition CreateTransition<T>(
AvaloniaProperty targetProperty,
TimeSpan? duration = null, // 默认 300ms
Easing? easing = null // 默认 LinearEasing
) where T : TransitionBase, new()
5. AnimationExtensions — 无限循环动画
// 在取消前无限循环播放动画
await animation.RunInfiniteAsync(control, cancellationToken);
内部将 IterationCount 设为 1,在循环中反复调用 RunAsync,直到 CancellationToken 被取消。用于图标旋转(Spin)等需要持续播放的场景。
6. AnimatableReflectionExtensions — Animatable 状态控制
通过反射访问 Avalonia Animatable 类的私有方法,实现过渡的启用/禁用:
animatable.EnableTransitions(); // 启用过渡
animatable.DisableTransitions(); // 禁用过渡
使用 [DynamicDependency] 特性确保 AOT/Trimming 安全。
类型继承体系
Avalonia.Animation.TransitionBase
└── Avalonia.Animation.InterpolatingTransitionBase<T>
├── BoxShadowsTransition (非通知型)
├── SolidColorBrushTransition (非通知型,支持跨类型画刷)
└── AbstractNotifiableTransition<T> (可通知基类)
├── NotifiableBoolTransition
├── NotifiableDoubleTransition
├── NotifiableFloatTransition
├── NotifiableIntegerTransition
├── NotifiablePointTransition
├── NotifiableRelativePointTransition
├── NotifiableSizeTransition
├── NotifiableThicknessTransition
├── NotifiableVectorTransition
├── NotifiableCornerRadiusTransition
├── NotifiableBoxShadowsTransition
└── NotifiableTransformOperationsTransition
设计模式
| 模式 | 应用 |
|---|---|
| 工厂模式 | BaseTransitionUtils.CreateTransition<T>() 创建类型化过渡实例 |
| 委托模式 | 所有过渡将插值计算委托给 InterpolateUtils |
| 模板方法 | AbstractNotifiableTransition<T> 定义骨架,子类覆写 Interpolate |
| 观察者模式 | INotifyTransitionCompleted 同时支持事件和响应式流 |
| 策略模式 | 不同类型使用不同的插值策略(颜色、向量、画刷、变换等) |
与 MotionScene 的关系
MotionScene 系统在创建 Motion 时,使用本系统提供的过渡类型来驱动属性动画:
AbstractMotion.ConfigureTransitions()调用BaseTransitionUtils.CreateTransition<T>()创建过渡- 过渡被添加到
IMotion.Transitions列表 - 当 MotionActor 播放时,Avalonia 调用各过渡的
Interpolate()方法 InterpolateUtils执行实际的数值计算- 动画完成时通过
INotifyTransitionCompleted通知 MotionScene
相关文档
- MotionScene 概览 — 上层动效编排系统
- MotionScene 架构 — Actor-Motion 架构设计
- 内置动效参考 — 预置动效类型
- 主题系统概览 — 动画时长 Token 来源