カスタム アニメーションの概要
ここでは、カスタム キー フレームまたはアニメーション クラスを作成するか、フレームごとのコールバックを使用してアニメーション システムをバイパスすることにより、WPF のアニメーション システムを拡張する方法とタイミングを説明します。
必要条件
このトピックを理解するには、WPF が提供するさまざまな種類のアニメーションに精通している必要があります。 詳細については、「From/To/By アニメーションの概要」、「キー フレーム アニメーションの概要」、および「パス アニメーションの概要」を参照してください。
アニメーション クラスは Freezable クラスを継承するため、Freezable オブジェクトおよび Freezable クラスの継承方法に精通している必要があります。 詳細については、「Freezable オブジェクトの概要」を参照してください。
アニメーション システムの拡張
WPF アニメーション システムの拡張方法は、使用する組み込み機能のレベルに応じて多数あります。 WPF のアニメーション エンジンには、次の 3 つの主要な拡張ポイントがあります。
DoubleKeyFrame など *<Type>*KeyFrame クラスの 1 つを継承することにより、カスタム キー フレーム オブジェクトを作成します。 この方法では、WPF のアニメーション エンジンの組み込み機能のほとんどを使用します。
AnimationTimeline を継承するか、*<Type>*AnimationBase クラスの 1 つを継承することにより、独自のアニメーション クラスを作成します。
フレームごとのコールバックを使用してフレーム ベースのアニメーションを生成します。 この方法は、アニメーションとタイミング システムを完全にバイパスします。
アニメーション システムを拡張するためのいくかのシナリオを次の表に示します。
目的 |
使用する方法 |
---|---|
対応する <Type>AnimationUsingKeyFrames を持つ型の値間の補間をカスタマイズする |
カスタム キー フレームを作成します。 詳細については、「カスタム キー フレームの作成」を参照してください。 |
対応する <Type>Animation を持つ型の値間の補間以上のものもカスタマイズする |
アニメーション化する型に対応する <Type>AnimationBase クラスを継承する、カスタム アニメーション クラスを作成します。 詳細については、「カスタム アニメーション クラスの作成」を参照してください。 |
対応する WPF アニメーションを持たない型をアニメーション化する |
ObjectAnimationUsingKeyFrames を使用するか、AnimationTimeline を継承するクラスを作成します。 詳細については、「カスタム アニメーション クラスの作成」を参照してください。 |
オブジェクトの最後の一連のやり取りに基づいてフレームごとに計算された値で、複数のオブジェクトをアニメーション化する |
フレームごとのコールバックを使用します。 詳細については、「フレームごとのコールバックの使用」を参照してください。 |
カスタム キー フレームの作成
カスタム キー フレーム クラスの作成は、アニメーション システムを拡張する最も簡単な方法です。 この方法は、キーフレーム アニメーションに対して別の補間方式が必要な場合に使用します。 「キー フレーム アニメーションの概要」で説明しているように、キー フレーム アニメーションは、キー フレーム オブジェクトを使用してその出力値を生成します。 各キー フレームオブジェクトは、次の 3 つの機能を実行します。
その Value プロパティを使用してターゲットの値を指定します。
その KeyTime プロパティを使用して値に達する時間を指定します。
InterpolateValueCore メソッドを実装して、前のキー フレームの値とその独自の値の間を補間します。
実装手順
*<Type>*KeyFrame 抽象クラスから派生して、InterpolateValueCore メソッドを実装します。 InterpolateValueCore メソッドは、キー フレームの現在の値を返します。 このメソッドは、前のキー フレームの値と、0 ~ 1 の進行状況を示す値の 2 つのパラメーターを受け取ります。 進行状況 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 メソッドは、アニメーションの現在の値を返します。 このメソッドは、提示される開始値および終了値、およびアニメーションの進行状況を確認するために使用する AnimationClock の 3 つのパラメーターをとります。
*<Type>*AnimationBase クラスは Freezable クラスを継承するため、CreateInstanceCore コアをオーバーライドして、クラスの新しいインスタンスを返す必要もあります。 クラスがデータの格納に依存関係プロパティを使用していない場合や、作成後に追加の初期化を必要とする場合は、状況に応じて上記以外のメソッドをオーバーライドする必要が生じます。詳細については、「Freezable オブジェクトの概要」を参照してください。
詳細については、アニメーション化する型の *<Type>*AnimationBase クラスの GetCurrentValueCore メソッドのドキュメントを参照してください。 例については、カスタム アニメーションのサンプルを参照してください。
別の方法
単にアニメーション値を補間する方法を変更する場合は、*<Type>*KeyFrame クラスの 1 つから派生することをお勧めします。 作成したキー フレームは、WPF が提供する、対応する *<Type>*AnimationUsingKeyFrames で使用できます。
AnimationTimeline からの派生
一致する WPF アニメーションを持っていない型に対してアニメーションを作成する場合や、厳密に型指定されていないアニメーションを作成する場合は、AnimationTimeline クラスから派生します。
実装手順
AnimationTimeline クラスから派生して、次のメンバーをオーバーライドします。
CreateInstanceCore – 新しいクラスが具象クラスである場合、CreateInstanceCore をオーバーライドしてクラスの新しいインスタンスを返す必要があります。
GetCurrentValue – このメソッドをオーバーライドして、アニメーションの現在の値を返します。 このメソッドは、既定の開始値、既定の終了値、および AnimationClock の 3 つのパラメーターをとります。 AnimationClock を使用して、現在の時刻またはアニメーションの進行状況を取得します。 既定の開始値および終了値を使用するかどうかを選択できます。
IsDestinationDefault – このプロパティをオーバーライドして、GetCurrentValue メソッドで指定されている既定の終了値をアニメーションで使用するかどうかを示します。
TargetPropertyType – このプロパティをオーバーライドして、アニメーションが生成する出力値の Type を示します。
クラスがデータの格納に依存関係プロパティを使用していない場合や、作成後に追加の初期化を必要とする場合は、状況に応じて上記以外のメソッドをオーバーライドする必要が生じます。詳細については、「Freezable オブジェクトの概要」を参照してください。
(WPF アニメーションで使用される) 推奨されるパラダイムは、次の 2 つの継承レベルを使用することです。
AnimationTimeline から派生した抽象 *<Type>*AnimationBase クラスを作成します。 このクラスは、TargetPropertyType メソッドをオーバーライドする必要があります。 また、新しい抽象メソッド GetCurrentValueCore を導入し、GetCurrentValue をオーバーライドして、既定の開始値パラメーターと既定の終了値パラメーターの型を検証してから、GetCurrentValueCore を呼び出す必要があります。
新しい *<Type>*AnimationBase クラスを継承する別のクラスを作成し、CreateInstanceCore メソッド、導入した GetCurrentValueCore メソッド、および IsDestinationDefault プロパティをオーバーライドします。
別の方法
対応する From/To/By アニメーションまたはキーフレーム アニメーションを持たない型をアニメーション化する場合は、ObjectAnimationUsingKeyFrames の使用をお勧めします。 ObjectAnimationUsingKeyFrames は弱く型指定されているため、どの型の値でもアニメーション化できます。 この方法の欠点は、ObjectAnimationUsingKeyFrames が離散補間のみをサポートするということです。
フレームごとのコールバックの使用
この方法は、WPF アニメーション システムを完全にバイパスする必要がある場合に使用します。 この方法の 1 つのシナリオは、アニメーションの各ステップで、オブジェクトの最後の一連のやり取りに基づいてアニメーション化されたオブジェクトの新しい方向や位置の再計算が必要になる物理アニメーションです。
実装手順
これまで説明してきた他の方法とは異なり、フレームごとのコールバックを使用する場合、カスタムのアニメーションやキー フレームのクラスを作成する必要はありません。
代わりに、アニメーション化するオブジェクトを格納しているオブジェクトの Rendering イベントで登録します。 このイベント ハンドラー メソッドは、フレームごとに 1 回呼び出されます。 WPF がビジュアル ツリーの永続化されたレンダリング データを構成ツリーにマーシャリングするたびに、イベント ハンドラー メソッドが呼び出されます。
イベント ハンドラーでは、アニメーション効果に必要なあらゆる計算を実行し、これらの値を使用してアニメーション化するオブジェクトのプロパティを設定します。
現在のフレームの表現時間を取得するには、このイベントに関連付けられている EventArgs を、RenderingEventArgs としてキャストできます。これにより、現在のフレームのレンダリング時間を取得するために使用できる RenderingTime プロパティが提供されます。
詳細については、Rendering のページを参照してください。