动画 (DirectComposition)

注意

对于 Windows 10 上的应用,建议使用 Windows.UI.Composition API 而不是 DirectComposition。 有关详细信息,请参阅 使用视觉对象层实现桌面应用的现代化

本主题讨论 Microsoft DirectComposition 动画的基础知识。 本节包含以下主题:

什么是动画?

动画 是在每次更改后重新绘制视觉对象时,在一段时间内快速对视觉对象进行增量更改而创建的视觉错觉。 由于重绘发生得很快,大脑会将增量变化视为一个不断变化的场景,就像在电影或实时动作视频中一样。

下表介绍了使用动画的一些典型方法。

动画 说明
滚动 使用动画将物理模拟动量等功能添加到滚动列表控件。
场景切换 使用动画创建导航场景切换,在工作流中的任务之间提供连续性。 导航场景切换提供上下文,向用户显示他们已到过的位置、他们所处的位置和下一步需要前往的位置。
跨窗口交互 对不同应用程序的 UI 元素进行动画处理,使它们能够感知到它们之间的无缝连续性,从而帮助用户完成涉及从一个应用程序切换到另一个应用程序的任务。

 

可进行动画处理的属性

在 DirectComposition 中,通过将动画应用于定义视觉对象的单个属性来对视觉对象进行动画处理。 例如,如果要在屏幕上水平移动视觉对象,可将动画应用于视觉对象的 OffsetX 属性。 同样,如果要对视觉对象执行简单的 2D 动画旋转,可将动画应用于 2D 转换对象的 Angle 属性,然后将 2D 转换对象应用于视觉对象的 Transform 属性。

使用 DirectComposition 可以将动画应用于采用标量值的任何对象属性。 可以将同时动画应用于多个属性和多个对象。

DirectComposition 在单独的线程上运行动画。 可以启动动画或动画集,然后在应用程序线程上执行其他工作,甚至可以将线程置于睡眠状态,而合成引擎则以适当的帧速率运行动画。

动画函数

DirectComposition 基于定义的动画函数对对象属性进行动画处理。 动画函数是一种构造,用于指定对象属性的值在一段时间内的更改方式。 例如,可以定义一个动画函数,该函数在 4 秒内将属性的值从 1 更改为 360。 然后,如果将动画函数应用于 2D 旋转转换对象的 Angle 属性,然后将转换对象应用于视觉对象的 Transform 属性,动画函数将在 4 秒内以整圈形式旋转视觉对象。

动画函数由调用 IDCompositionDevice::CreateAnimation 方法创建的动画对象表示。 使用动画对象的 IDCompositionAnimation 接口的方法创建动画函数,一次一个将 动画段追加到定义动画函数的数组中。 追加段时,指定一个从零开始的偏移量,用于标记段的开始时间(相对于动画函数的开始时间)。 动画段必须按开始时间的增加顺序追加。 尝试追加开始时间早于或等于上一段的动画段将失败。 动画函数可以具有指定的结束时间,指示函数应何时结束。

除非另行指定,否则动画函数在桌面窗口管理器 (DWM) 收到执行动画的命令时启动。 每个段将一直运行到到达下一段的开始时间。 段之间的动画属性值中发生的任何不连续更改都被视为离散更改。

通过将属性值设置为表示动画函数的动画对象的 IDCompositionAnimation 指针,可以将动画函数应用于属性。 同一动画对象可以应用于同一对象的多个属性,以及同一设备创建的其他对象的属性。

动画段

动画段是动画函数的基本计时定义;它们是从中生成更复杂的更高级别的动画函数的基元。 动画段由一系列参数构成,这些参数描述函数和段开始的时间(相对于动画函数的开头)。 对于每个段,时间 (t) 沿水平轴进行,从 t = 0 开始。

立方段

三次段的计时由立方多项式定义。 对于给定的时间输入 (t) ,输出值由以下公式提供:

x (t) = atー + bt² + ct + d

下图显示了包含两个立方段的动画函数。 第一个段在 4 秒内将值从 0 转换为 16,第二段在接下来的 4 秒内将值从 16 线性更改为 0。 第一个转换沿此立方多项式发生:

x (t) = tー - 6t² + 12t

第二个转换将沿此转换进行:

x (t) = - 4t + 16

具有两个立方段的动画函数示意图

使用 IDCompositionAnimation::AddCubic 方法将立方段添加到动画函数。

正弦段

正弦段的计时由以下公式定义:

x (t) = 偏置 + 振幅 * sin (t*Frequency*2*PI + Phase*PI/180.0)

使用 IDCompositionAnimation::AddSinusoidal 方法将正弦段添加到动画函数。

重复段

重复段重复动画函数的上一个指定部分。 重复段会导致动画函数的指定部分无限期循环,直到遇到下一段或到达动画的指定末尾。 动画的上一部分由其他段(包括其他重复段)组成。 重复段不能用作动画函数中的第一个段。

下图显示了一个动画函数,该函数由两个 4 秒持续时间的三次方段组成,后跟一个持续 12 秒的重复段。 重复段从 8 秒开始进入动画,并重复动画的前 6 秒两次,直到 20 秒达到结束段。

包含两个三次段和一个重复段的动画函数的示意图

若要向动画函数添加重复段,请使用 IDCompositionAnimation::AddRepeat 方法。

结束段

从段构造动画函数后,可以追加结束段,使动画函数在特定时间结束。 如果不追加结束段,动画函数的最终段将无限期运行。

通过调用 IDCompositionAnimation::End 方法追加结束段,指定动画函数开头的偏移量,该偏移量指示函数的终点。 偏移量必须大于上一段的起始偏移量。 此外,结束段不能用作动画函数中的第一个基元。

调用 End 时,还会为要进行动画处理的属性指定最终值。 当达到动画函数的终点时,属性设置为指定的最终值。

追加结束段后,不能将任何其他段追加到动画函数。 也就是说,除 IDCompositionAnimation::Reset 外,对动画对象的所有方法调用都失败。 调用 Reset 会将动画对象返回到干净状态,其中动画函数不包含任何段,此时可以再次添加段。

与 Windows 动画管理器的兼容性

Windows 动画管理器 (Windows 动画) 输出与 DirectComposition API 兼容的格式的动画基元。 这意味着 DirectComposition 可以根据 Windows 动画创建的动画基元创建动画。

有关详细信息,请参阅 Windows 动画管理器IUIAnimationVariable2::GetCurve 方法和 使用 Windows 动画管理器 v2 管理 DirectComposition 动画

DirectComposition 概念