基于时间的动画

当某个组件或整个用户体验发生更改时,最终用户通常会以两种方式观察它:随着时间的推移或即时观察。 在 Windows 平台上,前者优于后者——用户体验的即时更改常常使最终用户感到困惑和惊讶,因为他们无法理解所发生的事情。 然后,最终用户将体验视为不和谐和不自然。

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

基于时间的动画的类型

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

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

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

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

  • 颜色关键帧动画
  • 四元数关键帧动画
  • 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);

让我们来看一个示例,以便看看这个公式的实际应用效果。

示例:

在此示例中,你想在 1 秒钟内将视觉对象的偏移量从 <0,0,0> 动画到 <200,0,0>。 此外,你想要看到这些位置之间的视觉动画 10 次。

关键帧动画

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

接下来,由于你想要对 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);
}