动画和计时系统概述

本主题介绍计时系统如何使用动画 TimelineClock 类对属性进行动画处理。

先决条件

若要了解本主题,应能够使用 WPF 动画对属性进行动画处理,如 动画概述中所述。 它还有助于熟悉依赖项属性;有关详细信息,请参阅 依赖项属性概述

时间线和时钟

动画概述介绍了如何Timeline表示时间段,动画是生成输出值的类型的Timeline动画。 单纯一个 Timeline 除了描述一段时间之外,什么都不做。 它是时间线 Clock 的对象,它执行实际工作。 同样,动画实际上不会对属性进行动画处理:动画类描述应如何计算输出值,但它是为 Clock 驱动动画输出并将其应用于属性的动画创建的。

A Clock 是一种特殊类型的对象,用于维护与 Timeline计时相关的运行时状态。 它提供对动画和计时系统至关重要的三位信息: CurrentTimeCurrentProgressCurrentState。 A Clock 使用其 Timeline 中描述的计时行为来确定当前的时间、进度和状态: DurationRepeatBehaviorAutoReverse等等。

在大多数情况下,系统会自动为时间线创建 a Clock 。 使用 StoryboardBeginAnimation 方法进行动画处理时,会自动为时间线和动画创建时钟,并应用于其目标属性。 还可以通过使用您的TimelineCreateClock方法显式创建ClockMediaTimeline.CreateClock 方法为调用它的 Timeline 创建一个相应类型的时钟。 Timeline如果包含子时间线,它还会为其创建Clock对象。 生成的 Clock 对象排列在与创建对象树的结构匹配的 Timeline 树中。

不同类型的时间线有不同的时钟类型。 下表显示了 Clock 与某些不同 Timeline 类型对应的类型。

时间线类型 时钟类型 时钟用途
动画 (继承自 AnimationTimeline AnimationClock 为依赖属性生成输出值。
MediaTimeline MediaClock 处理媒体文件。
ParallelTimeline ClockGroup 对其子 Clock 对象进行分组和控制
Storyboard ClockGroup 对其子 Clock 对象进行分组和控制

可以使用该方法将创建的任何 AnimationClock 对象应用到兼容的依赖项属性 ApplyAnimationClock

在性能密集型方案中,例如对大量类似对象进行动画处理,管理自己的 Clock 使用可提供性能优势。

时钟和时间管理器

在 WPF 中对对象进行动画处理时,时间管理器管理为时间线创建的 Clock 对象。 时间管理器是对象树的 Clock 根,控制该树中的时间流。 时间管理器会自动为每个 WPF 应用程序创建,并且对应用程序开发人员不可见。 时间管理器每秒会滴答多次;每秒实际发生的滴答次数会因系统资源的可用性而有所不同。 在上述每个时钟周期中,时间管理器计算计时树中所有 ActiveClock 对象的状态。

以下图示显示了时间管理器、AnimationClock,以及一个动画依赖属性之间的关系。

计时系统组件和时间管理器。
对属性进行动画处理

当时间管理器滴答作响时,它会更新应用程序中每个 ActiveClock 时间。 如果ClockAnimationClock,它使用创建它的AnimationTimelineGetCurrentValue方法来计算其当前输出值。 AnimationTimeline提供AnimationClock当前本地时间、输入值(通常是属性的基值)和默认目标值。 使用 GetValue 方法或其 CLR 访问器检索被属性动画化的值时,将获得其 AnimationClock 的输出。

时钟组

上一部分介绍了与不同类型的时间线相对应的不同种类的Clock对象。 下图显示了时间管理器、一个 ClockGroup、一个 AnimationClock和一个动画依赖属性之间的关系。 为汇集其他时间线的时间表(例如 Storyboard 类,该类将动画和其他时间线组合在一起)创建一个ClockGroup

具有时间管理器和依赖项属性的计时系统组件。
时钟组

组成

可以将多个时钟与单个属性相关联,在这种情况下,每个时钟都使用上述时钟的输出值作为其基值。 下图显示了应用于同一属性的三个 AnimationClock 对象。 Clock1 使用动画属性的基值作为其输入,并使用它生成输出。 Clock2 采用 Clock1 的输出作为其输入,并使用它生成输出。 Clock3 采用 Clock2 的输出作为其输入,并使用它生成输出。 当多个时钟同时影响同一属性时,它们据说位于合成链中。

由多个依赖项属性组成的计时系统组件。
合成链

请注意,尽管在组合链中对象的输入和输出 AnimationClock 之间创建了关系,但是它们的计时行为不会受到影响; Clock 对象(包括 AnimationClock 对象)对其父 Clock 对象具有分层依赖关系。

若要将多个时钟应用于同一属性,请在应用 ComposeHandoffBehaviorStoryboard 动画或 AnimationClock 时使用。

时钟周期和事件合并

除了计算输出值外,时间管理器在每次计时时执行其他工作:它确定每个时钟的状态,并根据需要引发事件。

尽管时钟周期频繁发生,但是不同时钟周期之间可能会很多操作。 例如, Clock 可能会再次停止、启动和停止,在这种情况下,其 CurrentState 值将更改三次。 从理论上讲, CurrentStateInvalidated 事件可以在单个时钟周期中多次引发;但是,计时引擎会合并事件,以便 CurrentStateInvalidated 每个时钟周期最多可以引发一次事件。 对于所有计时事件都是如此:对于给定 Clock 对象,最多会引发每种类型的一个事件。

Clock 在时钟周期之间切换状态并返回到其原始状态时(例如从 Active 变为 Stopped 再返回到 Active),关联的事件仍然会发生。

有关计时事件的详细信息,请参阅 计时事件概述

属性的当前值和基值

可动画属性可以有两个值:基值和当前值。 使用 CLR 访问器或 SetValue 方法设置属性时,可以设置其基值。 当属性未进行动画处理时,其基值和当前值相同。

在为属性设置动画时,AnimationClock 会设置该属性的 当前 值。 当AnimationClockActiveFilling时,通过其 CLR 访问器或GetValue方法检索属性的值,将返回AnimationClock的输出。 可以使用该方法检索属性的基值 GetAnimationBaseValue

另请参阅