自訂動畫概觀
本主題描述如何及何時建立自訂主要畫面格、動畫類別,或使用個別畫面格回呼來略過 WPF 動畫系統。
必要條件
若要瞭解本主題,您應該熟悉 WPF 所提供的不同類型的動畫。 如需詳細資訊,請參閱<From/To/By 動畫概觀>、主要畫面格動畫概觀以及路徑動畫概觀。
因為動畫類別繼承自 Freezable 類別,因此您應該熟悉 Freezable 物件,以及如何繼承自 Freezable 。 如需詳細資訊,請參閱 Freezable 物件概觀。
擴充動畫系統
根據您想要使用的內建功能層級而定,有數種方式可以擴充 WPF 動畫系統。 WPF 動畫引擎中有三個主要擴充點:
繼承自其中一個 * < Type > *KeyFrame 類別,例如 DoubleKeyFrame ,以建立自訂主要畫面格物件。 此方法會使用 WPF 動畫引擎的大部分內建功能。
繼承自 AnimationTimeline 或其中一個 * < Type > *AnimationBase 類別,以建立您自己的動畫類別。
您可以針對每一畫面格使用每一畫面的回呼來產生動畫。 這個方法完全略過動畫與計時系統。
下表說明一些擴充動畫系統的案例。
當您要... | 使用這個方法 |
---|---|
自訂具有對應 * < Type > *AnimationUsingKeyFrames 的類型值之間的插補 | 建立自訂主要畫面格。 如需詳細資訊,請參閱建立自訂主要畫面格一節。 |
自訂具有對應 * < Type > *Animation 之型別值之間的插補點。 | 建立繼承自 * < Type > *AnimationBase 類別的自訂動畫類別,該類別對應至您想要產生動畫效果的類型。 如需詳細資訊,請參閱建立自訂動畫類別一節。 |
建立沒有對應 WPF 動畫的類型動畫 | ObjectAnimationUsingKeyFrames使用 或 建立繼承自 AnimationTimeline 的類別。 如需詳細資訊,請參閱建立自訂動畫類別一節。 |
利用每個畫面格都會計算的值,並根據最後一組物件互動的值,以動畫顯示多個物件 | 使用每一畫面的回呼。 如需詳細資訊,請參閱使用每一畫面的回呼一節。 |
建立自訂主要畫面格
建立自訂主要畫面格類別是擴充動畫系統最簡單的方式。 當您想要不同的主要畫面格動畫內插補點方法時,請使用這個方法。 如主要畫面格動畫概觀中所述,主要畫面格動畫使用主要畫面格物件來產生其輸出值。 每個主要畫面格物件都會執行三個函式︰
實作指示
衍生自 * < Type > *KeyFrame 抽象類別,並實作 InterpolateValueCore 方法。 InterpolateValueCore 方法會傳回主要畫面格目前的值。 它接受兩個參數︰前一個主要畫面格的值和範圍從 0 到 1 的進度值。 0 的進度表示主要畫面格剛開始,而值為 1 表示主要畫面格剛剛完成,而且應該傳回其 Value 屬性所指定的值。
因為 * < Type > *KeyFrame 類別繼承自 Freezable 類別,因此您也必須覆寫 CreateInstanceCore 核心以傳回 類別的新實例。 如果類別不使用相依性屬性來儲存其資料或需要在建立之後額外進行初始化,您可能需要覆寫其他方法。如需詳細資訊,請參閱 Freezable 物件概觀。
建立自訂的 * < Type > *KeyFrame 動畫之後,您可以將它與該類型的 * < Type > *AnimationUsingKeyFrames 搭配使用。
建立自訂動畫類別
建立您自己的動畫類型可讓您更充分掌控物件的動畫效果。 建立您自己的動畫類型有兩種建議方式:您可以從 類別或 * < Type > *AnimationBase 類別衍生 AnimationTimeline 。 不建議從 * < Type*Animation 或 *Type >> * < AnimationUsingKeyFrames 類別衍生。
衍生自 < Type > AnimationBase
衍生自 * < Type > *AnimationBase 類別是建立新動畫類型最簡單的方式。 當您想要為已經有對應 * < Type > *AnimationBase 類別的類型建立新的動畫時,請使用此方法。
實作指示
衍生自 * < Type > *Animation 類別,並實作 GetCurrentValueCore 方法。 GetCurrentValueCore 方法會傳回動畫目前的值。 它採用三個參數:建議的起始值、建議的結束值,以及 AnimationClock 用來判斷動畫進度的 。
因為 * < Type > *AnimationBase 類別繼承自 Freezable 類別,因此您也必須覆寫 CreateInstanceCore 核心以傳回 類別的新實例。 如果類別不使用相依性屬性來儲存其資料或需要在建立之後額外進行初始化,您可能需要覆寫其他方法。如需詳細資訊,請參閱 Freezable 物件概觀。
如需詳細資訊,請參閱您想要建立動畫之類型之 * < Type > *AnimationBase 類別的 GetCurrentValueCore 方法檔。 如需範例,請參閱自訂動畫範例
替代方法
如果您只想變更動畫值的插補方式,請考慮衍生自其中一個 * < Type > *KeyFrame 類別。 您建立的主要畫面格可以與 WPF 所提供的對應 * < Type > *AnimationUsingKeyFrames 搭配使用。
衍生自 AnimationTimeline
如果您想要為還沒有相符 WPF 動畫的類型建立動畫,或想要建立不是強型別的動畫,請衍生自 AnimationTimeline 類別。
實作指示
衍生自 類別, AnimationTimeline 並覆寫下列成員:
CreateInstanceCore – 如果您的新類別是具象的,您必須覆寫 CreateInstanceCore 以傳回 類別的新實例。
GetCurrentValue – 覆寫此方法以傳回動畫的目前值。 它採用三個參數:預設原點值、預設目的地值和 AnimationClock 。 AnimationClock使用 取得動畫的目前時間或進度。 您可以選擇是否要使用預設的來源和目的值。
IsDestinationDefault – 覆寫此屬性,指出動畫是否使用 方法指定的 GetCurrentValue 預設目的地值。
TargetPropertyType – 覆寫這個屬性,以指出 Type 動畫產生的輸出。
如果類別不使用相依性屬性來儲存其資料或需要在建立之後額外進行初始化,您可能需要覆寫其他方法。如需詳細資訊,請參閱 Freezable 物件概觀。
建議的範例(WPF 動畫使用)是使用兩個繼承層級:
建立衍生自 AnimationTimeline 的抽象 * < Type > *AnimationBase 類別。 這個類別應該覆寫 TargetPropertyType 方法。 它也應該引進新的抽象方法 GetCurrentValueCore 和覆寫 GetCurrentValue ,以便驗證預設原始值和預設目的地值參數的類型,然後呼叫 GetCurrentValueCore。
建立另一個繼承自新 * < Type > *AnimationBase 類別的類別,並覆寫 CreateInstanceCore 方法、您介紹的 GetCurrentValueCore 方法,以及 IsDestinationDefault 屬性。
替代方法
如果您想要以動畫顯示沒有對應 From/To/By 動畫或主要畫面格動畫的類型,請考慮使用 ObjectAnimationUsingKeyFrames 。 因為它是弱型別,所以 ObjectAnimationUsingKeyFrames 可以產生任何類型的值動畫。 此方法的缺點是 ObjectAnimationUsingKeyFrames 只支援離散插補。
使用每一畫面的回呼
當您需要完全略過 WPF 動畫系統時,請使用此方法。 此方法的一個案例為物理動畫,其中的每個動畫步驟都需要根據最後一組物件互動來重新計算動畫物件的新方向或位置。
實作指示
和本概觀中所述的其他方法不同,若要使用每一畫面的回呼,您不需要建立自訂動畫或主要畫面格類別。
相反地,您會註冊 Rendering 包含您要產生動畫效果之物件的 物件事件。 系統會針對每個畫面呼叫一次此事件處理常式方法。 每次 WPF 將視覺化樹狀結構中保存的轉譯資料封送處理至組合樹狀結構時,都會呼叫事件處理常式方法。
在事件處理常式中,執行動畫效果所需的任何計算,並使用這些值設定您想要建立動畫的物件屬性。
若要取得目前畫面格的呈現時間, EventArgs 與此事件相關聯的 可以轉換成 RenderingEventArgs ,以提供 RenderingTime 屬性,讓您可用來取得目前畫面的轉譯時間。
如需詳細資訊,請參閱 Rendering 頁面。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應