基于时间的动画

当某个组件或整个用户体验发生更改时,最终用户通常会以两种方式观察到它:随着时间推移更改或突然更改。 在 Windows 平台上,前者是首选 - 瞬间发生改变的用户体验通常会让用户感到困惑和惊讶,因为他们无法马上明白发生了什么。 最终用户会觉得这种体验不和谐且不自然。

相反,你可以随着时间的推移更改 UI 来指导最终用户完成操作,或通知他们对体验的更改。 在 Windows 平台上,这是通过使用基于时间的动画(也称为 KeyFrameAnimations)完成的。 通过 KeyFrameAnimations,可以随时间推移更改 UI 并控制动画的各个方面,包括动画的开始方式和时间,以及它如何达到其结束状态。 例如,用超过 300 毫秒的时间将对象动画移动到新位置比立即将其“传送”到那里更令人愉快。 使用动画而不是突然更改时,最终的结果是更愉快和更吸引人的体验。

基于时间的动画类型

有两类基于时间的动画可用于在 Windows 上生成美观的用户体验:

显式动画 - 顾名思义,显式启动动画进行更新。 隐式动画 – 满足条件时,系统会代表你启动这些动画。

在本文中,我们将讨论如何通过 KeyFrameAnimations 创建和使用 基于时间的显式动画。

对于基于时间的显式和隐式动画,有不同的类型,对应于可以进行动画处理的 CompositionObject 属性的不同类型。

  • ColorKeyFrameAnimation
  • QuaternionKeyFrameAnimation
  • ScalarKeyFrameAnimation
  • Vector2KeyFrameAnimation
  • Vector3KeyFrameAnimation
  • Vector4KeyFrameAnimation

使用 KeyFrameAnimations 创建基于时间的动画

在介绍如何使用 KeyFrameAnimations 创建基于时间的显式动画之前,我们先来了解一些概念。

  • 关键帧 – 这些是动画将通过动画进行动画处理的单个“快照”。
    • 定义为密钥和值对。 该键表示 0 到 1 之间的进度,即在动画生存期内,此“快照”将发生的位置。 另一个参数表示此时的属性值。
  • KeyFrameAnimation 属性 – 可应用于满足 UI 需求的自定义选项。
    • DelayTime – 调用 StartAnimation 后动画开始前的时间。
    • 持续时间 – 动画的持续时间。
    • IterationBehavior – 动画的计数或无限重复行为。
    • IterationCount – 关键帧动画将重复的有限次数。
    • 关键帧计数 - 读取特定关键帧动画中的关键帧数。
    • StopBehavior – 指定调用 StopAnimation 时动画属性值的行为。
    • 方向 - 指定用于播放的动画方向。
  • 动画组 - 同时启动多个动画。
    • 经常在希望同时对多个属性进行动画处理时使用。

有关详细信息,请参阅 CompositionAnimationGroup

考虑到这些概念,我们来介绍构造 KeyFrameAnimation 的一般公式:

  1. 标识需要进行动画处理的 CompositionObject 及其各自的属性。
  2. 创建与要进行动画处理的属性类型匹配的合成器的 KeyFrameAnimation 类型模板。
  3. 使用动画模板开始添加关键帧并定义动画的属性。
    • 至少需要一个关键帧(100% 或 1f 关键帧)。
    • 建议同时定义持续时间。
  4. 准备好运行此动画后,请在 CompositionObject 上调用 StartAnimation(...),以要进行动画处理的属性为目标。 具体而言:
    • visual.StartAnimation("targetProperty", CompositionAnimation animation);
    • visual.StartAnimationGroup(AnimationGroup animationGroup);
  5. 如果有正在运行的动画,并且你希望停止动画或动画组,可以使用以下 API:
    • visual.StopAnimation("targetProperty");
    • visual.StopAnimationGroup(AnimationGroup AnimationGroup);

接下来的示例演示了此公式在操作中的作用。

示例

在本示例中,需要对从 <0,0,0> 到 <200,0,0> 超过 1 秒的视觉偏移进行动画处理。 此外,你想要看到这些位置之间的视觉动画 10 次。

Key frame animation

首先确定要进行动画处理的 CompositionObject 和属性。 在本例中,红色方块由一个名为 redVisual 的合成视觉对象表示。 从此对象启动动画。

接下来,由于你想要对 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 = Windows.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 = Windows.UI.Composition.AnimationDirection.Alternate;
    // Run animation for 10 times
    animation.IterationCount = 10;
    redVisual.StartAnimation("Offset", animation);
}