当某个组件或整个用户体验发生更改时,最终用户通常会以两种方式观察它:随着时间的推移或即时观察。 在 Windows 平台上,更偏向于使用前者——即时变化的用户体验常常使最终用户感到困惑和意外,因为他们无法理解发生了什么。 然后,最终用户会觉得这种体验是突兀且不自然的。
相反,你可以随着时间的推移更改 UI 来指导最终用户完成,或通知他们对体验的更改。 在 Windows 平台上,这是通过使用基于时间的动画(也称为 KeyFrameAnimations)完成的。 通过 KeyFrameAnimations,可以随时间推移更改 UI 并控制动画的各个方面,包括动画的开始方式和时间,以及它如何达到其结束状态。 例如,将对象动画移动到在300毫秒内的新位置,比瞬间“传送”到那更令人愉悦。 使用动画而不是即时更改时,净结果是一种更令人愉快和有吸引力的体验。
基于时间的动画的类型
有两类基于时间的动画可用于在 Windows 上生成美观的用户体验:
显式动画 - 顾名思义,您需要显式启动动画以进行更新。 隐式动画 – 满足条件时,系统会代表系统启动这些动画。
在本文中,我们将讨论如何通过 KeyFrameAnimations 创建和使用 基于时间的显式 动画。
对于基于显式和隐式时间的动画,有不同类型的,对应于可以进行动画处理的 CompositionObject 的不同类型的属性。
- 颜色关键帧动画
- 四元数关键帧动画
- ScalarKeyFrameAnimation
- Vector2关键帧动画
- Vector3KeyFrameAnimation
- Vector4关键帧动画
使用 KeyFrameAnimations 创建基于时间的动画
在介绍如何使用 KeyFrameAnimations 创建基于时间的显式动画之前,让我们来了解一些概念。
- 关键帧 – 这些是动画依次经过的单个“快照”。
- 定义为键和值对。 该键表示 0 到 1 之间的进度,即动画生存期内此“快照”发生的位置。 另一个参数表示此时的属性值。
- KeyFrameAnimation 属性 – 可应用的自定义选项以满足 UI 的需求。
- DelayTime – 调用 StartAnimation 后动画开始前的时间。
- 持续时间 – 动画的持续时间。
- IterationBehavior – 动画的计数或无限重复行为。
- IterationCount – 关键帧动画将重复的有限次数。
- 关键帧计数 - 读取特定关键帧动画中的关键帧数量。
- StopBehavior – 指定调用 StopAnimation 时动画属性值的行为。
- 方向 - 指定用于播放的动画方向。
- 动画组 - 同时启动多个动画。
- 经常在希望同时对多个属性进行动画处理时使用。
有关详细信息,请参阅 CompositionAnimationGroup。
考虑到这些概念,让我们来介绍构建 KeyFrameAnimation 的一般公式:
- 标识需要进行动画处理的 CompositionObject 及其各自的属性。
- 创建一个与要进行动画处理的属性类型相匹配的合成器的 KeyFrameAnimation 动画类型模板。
- 使用动画模板开始添加关键帧并定义动画的属性。
- 至少需要一个关键帧(100% 或 1f 关键帧)。
- 建议同时定义持续时间。
- 准备好运行此动画后,请在 CompositionObject 上调用 StartAnimation(...),以要进行动画处理的属性为目标。 具体而言:
visual.StartAnimation("targetProperty", CompositionAnimation animation);visual.StartAnimationGroup(AnimationGroup animationGroup);
- 如果你有正在运行的动画并且想要停止动画或动画组,则可以使用以下 API:
visual.StopAnimation("targetProperty");visual.StopAnimationGroup(AnimationGroup AnimationGroup);
让我们看一个示例,看看这个公式的实际应用。
示例
在此示例中,你想要将视觉对象的偏移量从 <0,0,0> 动画到 <200,0,0> 在 1 秒内。 此外,你希望看到这段位置间的动画效果重复出现 10 次。
首先确定要进行动画处理的 CompositionObject 和属性。 在本例中,红色方块由一个名为 redVisual 的Composition视觉对象表示。 动画从此对象开始。
接下来,由于你想要对 Offset 属性进行动画处理,因此需要创建 Vector3KeyFrameAnimation (Offset 的类型为 Vector3)。 还可以为 KeyFrameAnimation 定义相应的关键帧。
Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
animation.InsertKeyFrame(1f, new Vector3(200f, 0f, 0f));
然后,定义 KeyFrameAnimation 的属性来描述其持续时间以及两个位置(当前和 <200,0,0)>10 次之间动画的行为。
animation.Duration = TimeSpan.FromSeconds(2);
animation.Direction = Microsoft.UI.Composition.AnimationDirection.Alternate;
// Run animation for 10 times
animation.IterationCount = 10;
最后,若要运行动画,需要在 CompositionObject 的属性上启动它。
redVisual.StartAnimation("Offset", animation);
下面是完整的代码。
private void AnimateSquare(Compositor compositor, SpriteVisual redVisual)
{
Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
animation.InsertKeyFrame(1f, new Vector3(200f, 0f, 0f));
animation.Duration = TimeSpan.FromSeconds(2);
animation.Direction = Microsoft.UI.Composition.AnimationDirection.Alternate;
// Run animation for 10 times
animation.IterationCount = 10;
redVisual.StartAnimation("Offset", animation);
}