アニメーションとタイミング システムの概要

このトピックでは、タイミング システムがアニメーション、Timeline、および Clock クラスを使用してプロパティをアニメーション化する方法について説明します。

必須コンポーネント

このトピックを理解するには、「アニメーションの概要」で説明されているように、WPF のアニメーションを使ってプロパティをアニメーション化できる必要があります。 依存関係プロパティの理解も役に立ちます。詳しくは、「依存関係プロパティの概要」をご覧ください。

タイムラインとクロック

アニメーションの概要」では、Timeline が時間のセグメントを表す方法、およびアニメーションが出力値を生成する Timeline の種類であることを説明しました。 Timeline だけでは、時間のセグメントを記述すること以外何も行われません。 実際の処理を行うのは、タイムラインの Clock オブジェクトです。 同様に、アニメーションは実際にはプロパティをアニメーション化しません。アニメーション クラスでは出力値の計算方法が記述されますが、アニメーションの出力を生成してそれをプロパティに適用するのは、アニメーションに対して作成された Clock です。

Clock は、Timeline に対するタイミング関連の実行時状態を保持する特殊な種類のオブジェクトです。 これは、アニメーションとタイミング システムに不可欠な 3 つの情報である CurrentTimeCurrentProgressCurrentState を提供します。 Clock は、Timeline によって記述されるタイミング動作を使用して、現在時間、進行状況、状態を決定します (DurationRepeatBehaviorAutoReverse など)。

ほとんどの場合、Clock はタイムラインに対して自動的に作成されます。 Storyboard または BeginAnimation メソッドを使用してアニメーションを作成すると、タイムラインとアニメーションに対してクロックが自動的に作成されて、対象のプロパティに適用されます。 また、TimelineCreateClock メソッドを使用して Clock を明示的に作成することもできます。 MediaTimeline.CreateClock メソッドは、呼び出された Timeline に対して適切な型のクロックを作成します。 Timeline に子タイムラインが含まれる場合は、それらに対しても Clock オブジェクトを作成します。 結果の Clock オブジェクトは、作成元の Timeline オブジェクト ツリーの構造と一致するツリーに編成されます。

異なる型のタイムラインに対して異なる型のクロックがあります。 次の表では、Timeline の異なる型に対応する Clock の型を示します。

タイムラインの型 クロックの型 クロックの目的
Animation (AnimationTimelineから継承) AnimationClock 依存関係プロパティの出力値を生成します。
MediaTimeline MediaClock メディア ファイルを処理します。
ParallelTimeline ClockGroup 子の Clock オブジェクトをグループ化して制御します。
Storyboard ClockGroup 子の Clock オブジェクトをグループ化して制御します。

ApplyAnimationClock メソッドを使用することで、作成した AnimationClock オブジェクトを互換性のある依存関係プロパティに適用できます。

多数の似たオブジェクトのアニメーション化など、負荷の高いシナリオでは、独自の Clock の使用を管理するとパフォーマンスの利点があります。

クロックとタイム マネージャー

WPF でオブジェクトをアニメーション化するとき、タイムラインに対して作成された Clock オブジェクトを管理するのはタイム マネージャーです。 タイム マネージャーは Clock オブジェクトのツリーのルートで、そのツリー内の時間の流れを制御します。 タイム マネージャーは各 WPF アプリケーションに自動的に作成され、アプリケーション開発者には表示されません。 タイム マネージャーは 1 秒間に何度も "タイマーを刻み" ます。1 秒ごとに刻まれるタイマーの実際の数は、使用可能なシステム リソースによって異なります。 これらのティックごとに、タイム マネージャーはタイミング ツリー内のすべての ActiveClock オブジェクトの状態を計算します。

次の図では、タイム マネージャー、AnimationClock、およびアニメーション化される依存関係プロパティの間の関係を示します。

Timing system components and the time manager.
プロパティのアニメーション化

タイム マネージャーは、タイマーを刻むとき、アプリケーション内のすべての ActiveClock の時刻を更新します。 ClockAnimationClock の場合は、作成元の AnimationTimelineGetCurrentValue メソッドを使用して、現在の出力値を計算します。 AnimationClock は、AnimationTimeline に、現在のローカル時刻、入力値 (通常はプロパティの基本値)、既定の目標値を提供します。 GetValue メソッドまたはその CLR アクセサーを使用してプロパティによってアニメーション化された値を取得するときは、その AnimationClock の出力を取得します。

クロック グループ

前のセクションでは、タイムラインの異なる型に対して Clock オブジェクトの異なる型があることを説明しました。 次の図では、タイム マネージャー、ClockGroupAnimationClock、およびアニメーション化される依存関係プロパティの間の関係を示します。 ClockGroup は、アニメーションと他のタイムラインをグループ化する Storyboard クラスなど、他のタイムラインをグループ化するタイムラインに対して作成されます。

Timing system components with the time manager and dependency properties.
ClockGroup

コンポジション

複数のクロックを 1 つのプロパティと関連付けることができます。その場合、各クロックは前のクロックの出力値を基本値として使います。 次の図は、同じプロパティに適用された 3 つの AnimationClock オブジェクトを示したものです。 Clock1 は、アニメーション化されたプロパティの基本値を入力として使って、出力を生成します。 Clock2 は、Clock1 の出力を入力として受け取り、それを使って出力を生成します。 Clock3 は、Clock2 の出力を入力として受け取り、それを使って出力を生成します。 複数のクロックが同じプロパティに同時に影響を与える場合、それらはコンポジション チェーン内にあると言います。

Timing system components composed with multiple dependency properties.
コンポジション チェーン

コンポジション チェーン内の AnimationClock オブジェクトの入力と出力の間には関係が作成されますが、それらのタイミング動作は影響を受けません。Clock オブジェクト (AnimationClock オブジェクトを含みます) には、親の Clock オブジェクトに対する階層的依存関係があります。

複数のクロックを同じプロパティに適用するには、Storyboard、アニメーション、または AnimationClock を適用するときに、ComposeHandoffBehavior を使用します。

ティックとイベントの統合

出力値を計算するだけでなく、タイム マネージャーはティックのたびに他の処理を行います。つまり、クロックの状態を判断し、必要に応じてイベントを発生させます。

ティックは頻繁に発生しますが、各ティックの間には多くのことが起こる可能性があります。 たとえば、Clock が停止し、開始し、再び停止することがあります。このような場合、CurrentState の値は 3 回変化します。 理論的には、1 回のティックで CurrentStateInvalidated イベントを複数回発生させることができます。ただし、タイミング エンジンは、CurrentStateInvalidated イベントがティックごとに多くても 1 回だけ発生するように、イベントを統合します。 これは、すべてのタイミング イベントにあてはまります。特定の Clock オブジェクトに対して生成される各種類のイベントは、多くても 1 回です。

ティックの間に Clock が状態を切り替えて元の状態に戻る場合でも (Active から Stopped になり、Active に戻る場合など)、関連するイベントが発生します。

タイミング イベントについて詳しくは、「タイミング イベントの概要」をご覧ください。

プロパティの現在値と基本値

アニメーション化可能なプロパティは、基本値と現在値の 2 つの値を持つことができます。 CLR アクセサーまたは SetValue メソッドを使用してプロパティを設定すると、基本値が設定されます。 プロパティがアニメーション化されない場合は、基本値と現在値は同じです。

プロパティをアニメーション化すると、AnimationClock はプロパティの "現在" の値を設定します。 CLR アクセサーまたは GetValue メソッドを使用してプロパティの値を取得すると、AnimationClockActive または Filling であるときの AnimationClock の出力が返されます。 プロパティの基本値は、GetAnimationBaseValue メソッドを使用して取得できます。

関連項目