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