分鏡腳本概觀
本概觀著重於 Windows 動畫中轉換和分鏡腳本的使用方式。 如需 Windows 動畫元件的概觀,請參閱 Windows 動畫概觀。
本主題包含下列幾節:
轉換
轉換會定義單一動畫變數如何在特定時間間隔內變更。 Windows 動畫包含一個通用轉換連結庫,開發人員可以套用至一或多個動畫變數。 不同類型的轉換有不同的參數集合,這可能包括轉換完成時變數的值、轉換的持續時間,或基礎數學函數特有的數量,例如加速或振蕩範圍。
所有轉換都會共用兩個隱含參數:數學函式的初始值和初始速度(斜率)。 這些可由應用程式明確指定,但通常會由動畫管理員設定為轉換開始時動畫變數的值和速度。
轉換連結庫
轉換連結庫目前提供下列轉換。 如果應用程式需要無法使用轉換連結庫指定的效果,開發人員可以實作應用程式的自定義插補器,或使用第三方轉換連結庫來建立其他類型的轉換。
轉換名稱 | 描述 |
---|---|
加速減速 |
動畫變數會加快速度,然後在指定的持續時間內變慢。 |
constant |
在整個轉換期間,動畫變數會維持在其初始值。 |
四方 |
動畫變數會從其初始值變更為指定的最終值,在指定的持續時間內具有指定的最終速度。 |
離散 |
動畫變數會維持在指定延遲時間的初始值,然後立即切換至指定的最終值,並在指定的保留時間維持在該值。 |
暫態 |
動畫變數會立即從目前的值變更為指定的最終值。 |
linear |
動畫變數會以線性方式從其初始值轉換至指定期間內指定的最終值。 |
從速度線性 |
動畫變數會以線性方式從其初始值轉換為具有指定速度的指定最終值。 |
加速的拋物 |
動畫變數會從其初始值轉換為指定的最終值,具有指定的最終速度,以指定的加速來變更其速度。 |
倒轉 |
變數會變更指定期間的方向。 最終值會與初始值相同,而最終速度將是初始速度的負數。 |
範圍中正弦數 |
變數在指定的值範圍內振蕩,在指定的期間內具有指定的振蕩期間。 |
來自速度的正弦 |
在指定的持續時間內,變數會以指定的振蕩期間振蕩。 振蕩的幅度取決於變數的初始速度。 |
平滑停止 |
動畫變數會在最大持續時間內,在指定的最終值上順利停止。 |
下表包含每個轉換的圖例。
插圖 |
---|
自訂轉換
插補器會定義數學函式,以決定動畫變數在從初始值到最終值時如何隨著時間變化。 轉換連結庫中的每個轉換都有一個相關聯的插補器物件,由系統提供並實作插補點函式。 如果應用程式需要無法使用轉換連結庫指定的效果,則可以針對每個新的轉換實作插補點物件,以實作一或多個自定義轉換。 插補器物件不能由應用程式直接使用,而且必須改為包裝在相關聯的轉換中。 轉換處理站可用來從插補器對象產生轉換。 如需詳細資訊,請參閱 IUIAnimationInterpolator 和 IUIAnimationTransitionFactory。
請注意,大部分的應用程式都會使用轉換連結庫來擁有所需的所有轉換,因此不需要實作插補程式。
Storyboard
分鏡腳本是一組經過一段時間套用至一或多個動畫變數的轉換。 分鏡腳本中的轉換保證會保持彼此的同步處理,而且分鏡腳本會排程或取消為單位。 建立所需的轉換之後,應用程式會使用動畫管理員建立分鏡腳本、將轉換新增至分鏡腳本、適當地設定分鏡腳本,並排程它儘快播放。 動畫管理員會決定分鏡腳本的實際開始時間,因為目前可能會與其他腳本產生相同變數動畫的競爭。
分鏡腳本的整體持續時間取決於分鏡腳本內轉換的持續時間。 轉換的持續時間不需要固定;它可以由轉換開始時動畫變數的值和速度來決定。 因此,分鏡腳本的持續時間也可以取決於其動畫的變數狀態。
下列範例假設已建立動畫管理員、轉換連結庫和定時器。 如需詳細資訊,請參閱 建立主要動畫物件。 這些範例也假設應用程式已使用 IUIAnimationManager::CreateAnimationVariable 方法建立三個動畫變數(X、Y 和 Z),並使用 IUIAnimationTransitionLibrary 介面的其中一個方法進行五個轉換(T1、T2、T3、T4 和 T5)。
建置簡單的分鏡腳本
若要建置簡單的分鏡腳本,請使用 IUIAnimationManager::CreateStoryboard 方法來建立新的分鏡腳本、IUIAnimationTransitionLibrary::CreateLinearTransition 方法來建立線性轉換、T1 和 IUIAnimationStoryboard::AddTransition 方法,將 T1 轉換套用至變數 X,並將產生的轉換新增至分鏡腳本。
此程式會產生簡單的分鏡腳本,如下圖所示。 分鏡腳本包含一個轉換 T1,因此變數 X 的值會在固定的時間期間內以線性方式變更。
請注意,針對這類簡單的案例,替代選項是使用 IUIAnimationManager::ScheduleTransition 方法。
使用上下文相關持續時間
雖然某些轉換有固定的持續時間,但其他轉換的持續時間取決於轉換開始時動畫變數的初始值或速度。 例如, IUIAnimationTransitionLibrary::CreateLinearTransitionFromSpeed 方法會建立與動畫變數初始值與指定最終值之間差異成正比的轉換。 在此圖中,和其餘的圖例中,具有任意持續時間的這類轉換會以問號 (?) 顯示,而當腳本播放時,會決定其實際持續時間。
建置更複雜的分鏡腳本
建立分鏡腳本並新增單一轉換之後,您可以再次呼叫 IUIAnimationStoryboard::AddTransition 方法,但使用 T2 而不是 T1,為 X 變數附加第二個轉換。
假設 T2 轉換具有區分內容的持續時間,分鏡腳本現在會包含影響變數 X 之任意持續時間的兩個背對背轉換。
再次使用變數 Y 呼叫 AddTransition,並轉換 T3 會在分鏡腳本開頭新增第三個轉換。 根據腳本播放時的 X 和 Y 值而定,T3 可能會在 T1 或 T2 之後結束。
使用主要畫面格
若要在分鏡腳本開頭的位移新增轉換,您必須先新增主要畫面格。 主要畫面格代表即時,而且本身不會影響分鏡腳本的行為。 每個分鏡腳本都有代表分鏡腳本開頭的隱含主要畫面格,UI_ANIMATION_KEYFRAME_STORYBOARD_START;您可以使用 UI_ANIMATION_KEYFRAME_STORYBOARD_START 呼叫 IUIAnimationStoryboard::AddKeyframeAtOffset 方法,以從頭開始的位移新增主要畫面格。
您新增主要畫面格的位移一律相對於另一個主要畫面格。 下圖顯示新增 keyframe1 和轉換 T4 的結果,其會套用至變數 Z、與 keyframe1 對齊,並以固定持續時間建立。 當然,由於還不清楚其他轉換的持續時間,T4 可能不是最後一次轉換完成。
使用 IUIAnimationStoryboard::AddKeyframeAfterTransition 方法,主要畫面格也可以放在轉換的結尾。 下圖顯示在 T1 之後新增 keyframe2 和 T2 之後的 keyframe3 的結果。
因為 T1 和 T2 的持續時間直到分鏡腳本播放才知道,主要畫面格 2 和 keyframe3 的位移也直到那時才確定。 因此,keyframe2 甚至 keyframe3 可能早於 keyframe1。
轉換的開始和結尾都可以使用 IUIAnimationStoryboard::AddTransitionBetweenKeyframes 方法,與主要畫面格對齊。 下圖顯示主要畫面格 2 與 keyframe3 之間,在變數 Y 上新增第五個轉換 T5 的結果。 這會改變 T5 的持續時間,根據 keyframe2 和 keyframe3 的相對位移,使 T5 的持續時間變長或較短。
持有變數
如果 T4 在 T2 和 T5 之後結束,分鏡腳本會停止動畫變數 X 和 Y,使其可供其他分鏡腳本產生動畫效果。 不過,應用程式可以呼叫 IUIAnimationStoryboard::HoldVariable 方法,要求分鏡腳本在其最終值上以動畫顯示部分或所有變數,直到分鏡腳本完成為止。 下圖顯示 T4 最後一次完成時,持有 X 和 Z 的結果。 請注意,腳本會在其最終值上保留 X,直到分鏡腳本完成為止。 保留不會影響 Z,因為分鏡腳本會在 T4 完成時結束。
雖然 Y 不是由這個分鏡腳本持有,但是除非其他分鏡腳本產生動畫效果,否則 T5 完成之後,其值不會變更。 因為 Y 未保留,因此任何其他分鏡腳本,不論優先順序為何,都可以在 T5 完成後以動畫顯示 Y。 相反地,因為會保留 X,所以在完成此分鏡腳本之前,較低優先順序的分鏡腳本無法讓 X 產生動畫效果。
所有這些圖例都假設腳本開始播放時,變數有一組任意的目前值。 如果遇到其他值,則內容敏感性轉換的持續時間可能會不同,如下圖所示。
在此案例中,T5 會在 T3 完成之前開始,因此會修剪 T3。 因為 T4 在 T2 和 T5 之前完成,因此 Z 的值會保留到分鏡腳本結尾為止。 一般而言,腳本開始播放時變數的值和速度可能會影響主要畫面格順序以及分鏡腳本的整體長度和形狀。
排程分鏡腳本
排程分鏡腳本時,其開始時間取決於其大綱和目前在排程中的分鏡腳本大綱。 具體來說,當分鏡腳本以動畫顯示每個個別變數時,第一個和最後一刻會判斷兩個分鏡腳本是否相撞,但內部轉換的內部詳細數據並不重要。
下圖顯示分鏡腳本的外框,其中五個轉換會以動畫顯示三個變數。
Windows 動畫平臺的基石是在必要時讓一個動畫在開始之前完成。 雖然這可消除許多邏輯問題,但它也會在UI中引入任意延遲。 為了解決這個問題,應用程式可以使用IUIAnimationStoryboard::SetLongestAcceptableDelay 方法,指定腳本開始時間最長的可接受延遲,而動畫管理員會使用這項資訊,在指定的延遲期間經過之前排程分鏡腳本。 排程分鏡腳本時,動畫管理員會決定其他分鏡腳本是否必須先取消、修剪、結束及/或壓縮。
應用程式可以註冊文本狀態變更時所呼叫的處理程式。 這可讓應用程式回應腳本開始播放、執行到完成、完全從排程中移除,或因較高優先順序分鏡腳本中斷而無法完成。 若要識別傳遞至分鏡腳本事件處理程式的分鏡腳本(或優先順序比較),應用程式可以使用 IUIAnimationStoryboard::SetTag 方法將標記套用至分鏡腳本,類似於可用來識別變數的腳本。 如同腳本重複使用一樣,開發人員在使用標記來識別分鏡腳本時必須小心,而且當用戶動作導致許多分鏡腳本排入佇列時,不會發生模棱兩可的情況。
下列範例顯示嘗試排程本主題先前章節中建置的分鏡腳本的兩種變化。
在此案例中,已排定六個分鏡腳本 A 到 F,以動畫顯示 W、X、Y 和 Z 變數,但只有 A 和 B 開始播放。 標示為 G 的新分鏡腳本,其最長可接受的延遲設定為下圖所示的持續時間。
應用程式已註冊包含下列邏輯的優先順序比較:
- G 只能取消 C 和 E,而且只能防止失敗。
- G 只能修剪 A、C、E 和 F,而且只能防止失敗。
- 任何分鏡腳本都可以壓縮任何其他分鏡腳本(壓縮一律只做為防止失敗)。
注意
限定符「只為了防止失敗」表示只有在 priorityEffect 參數UI_ANIMATION_PRIORITY_EFFECT_FAILURE時,已註冊的優先順序比較才會傳回S_OK。 如需詳細資訊, 請參閱 IUIAnimationPriorityComparison::HasPriority 方法。
若要在經過最長的可接受的延遲之前啟動 G,動畫管理員必須執行下列動作:
- 修剪 F
- 取消 E
取消 E 時,會發現 D 和 F 並還原成其原始大綱:
動畫管理員不需要取消或修剪 C,以在經過最長的可接受延遲之前排程,因此 C 和 G 的會議會決定 G 何時開始。
成功排程 G 之後,可以判斷其轉換的持續時間,因此已知其大綱的其餘部分。 不過,如果後續從排程中移除另一個分鏡腳本,大綱可能會變更。
在第二個範例中,請考慮上述案例,但針對 G 指定的延遲時間較短。
在此情況下,會採取下列動作:
- 修剪 F
- 取消 E
- 取消 C
此外,動畫管理員必須壓縮顯示的數量 D,讓 G 在最長的可接受延遲之後啟動,且稍後不要。
為了保留其相對時間,也會壓縮 A、B 和 F。
不過,不會壓縮不相關變數上的分鏡腳本(未顯示)。
G 的大綱現在已已知,而且與第一個案例的結果不同,因為變數在 G 開始時有不同的值。