カスタム アニメーションの概要

このトピックでは、カスタム キー フレームやアニメーション クラスを作成して、またはフレームごとのコールバックを使ってバイパスすることにより、WPF のアニメーション システムを拡張する方法と、それが必要な状況について説明します。

前提条件

このトピックを理解するには、WPF によって提供されるさまざまな種類のアニメーションに精通している必要があります。 詳しくは、「From/To/By アニメーションの概要」、「キー フレーム アニメーションの概要」、および「パス アニメーションの概要」をご覧ください。

アニメーションのクラスは Freezable クラスを継承するため、Freezable オブジェクトと、Freezable からの継承方法について、理解している必要があります。 詳しくは、「Freezable オブジェクトの概要」をご覧ください。

アニメーション システムの拡張

WPF のアニメーション システムには、使う組み込み機能のレベルに応じて、さまざまな拡張方法があります。 WPF のアニメーション エンジンには、次の 3 つの主な機能拡張ポイントがあります。

  • *<Type>*KeyFrame クラス (DoubleKeyFrame など) の 1 つから継承することにより、カスタム キー フレーム オブジェクトを作成します。 この方法では、WPF アニメーション エンジンの組み込み機能のほとんどを使います。

  • AnimationTimeline または *<Type>*AnimationBase クラスの 1 つから継承することにより、独自のアニメーション クラスを作成します。

  • フレームごとのコールバックを使って、フレームごとにアニメーションを生成します。 この方法は、アニメーションおよびタイミング システムを完全にバイパスします。

次の表では、いくつかのアニメーション システム拡張シナリオについて説明します。

目的... 使う方法
対応する *<Type>*AnimationUsingKeyFrames がある型の値の間の補間をカスタマイズする カスタム キー フレームを作成します。 詳しくは、「カスタム キー フレームを作成する」セクションをご覧ください。
対応する *<Type>*Animation がある型の値の間の補間以外の部分もカスタマイズする アニメーション化する型に対応する *<Type>*AnimationBase クラスを継承するカスタム アニメーション クラスを作成します。 詳しくは、「カスタム アニメーション クラスを作成する」セクションをご覧ください。
対応する WPF アニメーションがない型をアニメーション化する ObjectAnimationUsingKeyFrames を使用するか、または AnimationTimeline を継承するクラスを作成します。 詳しくは、「カスタム アニメーション クラスを作成する」セクションをご覧ください。
フレームごとに計算され、最後のオブジェクト相互作用セットに基づく値のある、複数のオブジェクトをアニメーション化する フレームごとのコールバックを使います。 詳しくは、「フレームごとのコールバックを使用する」セクションをご覧ください。

カスタム キー フレームを作成する

カスタム キー フレーム クラスの作成は、アニメーション システムを拡張する最も簡単な方法です。 キー フレーム アニメーションに対して異なる補間方法が必要なときは、このアプローチを使います。 「キー フレーム アニメーションの概要」で説明されているように、キー フレーム アニメーションはキー フレーム オブジェクトを使って出力値を生成します。 各キー フレーム オブジェクトは 3 つの機能を実行します。

  • Value プロパティを使用してターゲット値を指定します。

  • KeyTime プロパティを使用して、その値に到達する必要がある時間を指定します。

  • InterpolateValueCore メソッドを実装することで、前のキー フレームの値とそれ自体の値の間を補間します。

実装の説明

*<Type>*KeyFrame 抽象クラスから派生して、InterpolateValueCore メソッドを実装します。 InterpolateValueCore メソッドは、キー フレームの現在の値を返します。 2 つのパラメーターとして、前のキー フレームの値と、0 から 1 の範囲の進行状況の値を受け取ります。 進行状況 0 はキー フレームが開始したばかりであることを示し、値 1 はキー フレームが完了したばかりで、Value プロパティによって指定されている値を返す必要があることを示します。

*<Type>*KeyFrame クラスは Freezable クラスを継承するため、独自クラスの新しいインスタンスを返すように、CreateInstanceCore コアもオーバーライドする必要があります。 クラスが依存関係プロパティを使ってデータを保存しない場合、または作成の後で追加の初期化が必要な場合は、他のメソッドのオーバーライドが必要な場合があります。詳しくは、「Freezable オブジェクトの概要」をご覧ください。

カスタム *<Type>*KeyFrame アニメーションを作成した後は、その型の *<Type>*AnimationUsingKeyFrames でそれを使うことができます。

カスタム アニメーション クラスを作成する

独自のアニメーション型を作成すると、オブジェクトをアニメーション化する方法をいっそう細かく制御できます。 独自のアニメーション型を作成するには、2 つの推奨される方法があります。AnimationTimeline クラスから派生する方法と、*<Type>*AnimationBase クラスから派生する方法です。 *<Type>*Animation クラスまたは *<Type>*AnimationUsingKeyFrames クラスからの派生は推奨されません。

<Type>AnimationBase から派生する

*<Type>*AnimationBase クラスからの派生は、新しいアニメーション型を作成する最も簡単な方法です。 対応する *<Type>*AnimationBase クラスが既にある型の新しいアニメーションを作成する場合は、この方法を使います。

実装の説明

*<Type>*Animation から派生して、GetCurrentValueCore メソッドを実装します。 GetCurrentValueCore メソッドは、アニメーションの現在の値を返します。 これは、3 つのパラメーターとして、推奨される開始値、推奨される終了値、およびアニメーションの進行状況を特定するために使用する AnimationClock を受け取ります。

*<Type>*AnimationBase クラスは Freezable クラスを継承するため、独自クラスの新しいインスタンスを返すように、CreateInstanceCore コアもオーバーライドする必要があります。 クラスが依存関係プロパティを使ってデータを保存しない場合、または作成の後で追加の初期化が必要な場合は、他のメソッドのオーバーライドが必要な場合があります。詳しくは、「Freezable オブジェクトの概要」をご覧ください。

詳しくは、アニメーション化する型の *<Type>*AnimationBase クラスの GetCurrentValueCore メソッドのドキュメントをご覧ください。 例については、「Custom Animation Sample」(カスタム アニメーションのサンプル) をご覧ください。

別の方法

アニメーション値を補間する方法を変更したいだけの場合は、いずれかの *<Type>*KeyFrame クラスからの派生を検討します。 作成したキー フレームを、WPF によって提供される対応する *<Type>*AnimationUsingKeyFrames で使うことができます。

AnimationTimeline から派生する

一致する WPF アニメーションがまだ存在しない型のアニメーションを作成する場合、または厳密に型指定されていないアニメーションを作成したい場合は、AnimationTimeline クラスから派生します。

実装の説明

AnimationTimeline クラスから派生して、次のメンバーをオーバーライドします。

  • CreateInstanceCore – 新しいクラスが具象の場合、クラスの新しいインスタンスを返すように CreateInstanceCore をオーバーライドする必要があります。

  • GetCurrentValue – アニメーションの現在の値を返すように、このメソッドをオーバーライドします。 既定の開始値、既定の終了値、AnimationClock の、3 つのパラメーターを受け取ります。 アニメーションの現在の時間または進行状況を取得するには、AnimationClock を使用します。 既定の開始値と終了値を使うかどうかを選択できます。

  • IsDestinationDefaultGetCurrentValue メソッドによって指定された既定の終了値をアニメーションで使用するかどうかを示すために、このプロパティをオーバーライドします。

  • TargetPropertyType – アニメーションが生成する出力の Type を示すように、このプロパティをオーバーライドします。

クラスが依存関係プロパティを使ってデータを保存しない場合、または作成の後で追加の初期化が必要な場合は、他のメソッドのオーバーライドが必要な場合があります。詳しくは、「Freezable オブジェクトの概要」をご覧ください。

推奨される (WPF アニメーションによって使われる) パラダイムは、2 つの継承レベルを使うことです。

  1. AnimationTimeline から派生する抽象 *<Type>*AnimationBase クラスを作成します。 このクラスでは、TargetPropertyType メソッドをオーバーライドする必要があります。 また、新しい抽象メソッド GetCurrentValueCore を導入し、既定の開始値と終了値パラメーターの型を検証してから GetCurrentValueCore を呼び出すように GetCurrentValue をオーバーライドする必要があります。

  2. 新しい *<Type>*AnimationBase クラスから継承し、CreateInstanceCore メソッド、導入した GetCurrentValueCore メソッド、IsDestinationDefault プロパティをオーバーライドする、別のクラスを作成します。

別の方法

対応する From/To/By アニメーションまたはキー フレーム アニメーションがない型をアニメーション化する場合は、ObjectAnimationUsingKeyFrames の使用を検討します。 ObjectAnimationUsingKeyFramesは弱く型指定されているため、任意の型の値をアニメーション化できます。 この方法の欠点は、ObjectAnimationUsingKeyFrames が離散補間のみをサポートすることです。

フレームごとのコールバックを使用する

WPF アニメーション システムを完全にバイパスする必要があるときは、この方法を使います。 この方法の 1 つのシナリオは、各アニメーション ステップでオブジェクトの最後の一連のやり取りに基づいてアニメーション化されるオブジェクトの新しい向きまたは位置を再計算する必要がある物理アニメーションです。

実装の説明

この概要で説明されている他の方法とは異なり、フレームごとのコールバックを使うために、カスタム アニメーション クラスまたはカスタム キー フレーム クラスを作成する必要はありません。

代わりに、アニメーション化するオブジェクトを格納しているオブジェクトの Rendering イベントに登録します。 このイベント ハンドラー メソッドは、フレームごとに 1 回呼び出されます。 WPF がビジュアル ツリーの永続化されたレンダリング データを構成ツリーにマーシャリングするたびに、イベント ハンドラー メソッドが呼び出されます。

イベント ハンドラーでは、アニメーション効果に必要なあらゆる計算を実行し、これらの値を使用してアニメーション化するオブジェクトのプロパティを設定します。

現在のフレームの表現時間を取得するために、このイベントに関連付けられている EventArgs を、RenderingEventArgs としてキャストできます。これにより、現在のフレームのレンダリング時間を取得するために使用できる RenderingTime プロパティが提供されます。

詳細については、「Rendering」ページを参照してください。

関連項目