分鏡腳本概觀
本概觀著重於 Windows 動畫中轉換和分鏡腳本的使用方式。 如需 Windows 動畫元件的概觀,請參閱 Windows 動畫概觀。
本主題包含下列幾節:
轉換
轉換會定義單一動畫變數如何在特定時間間隔內變更。 Windows 動畫包含一個通用轉換連結庫,開發人員可以套用至一或多個動畫變數。 不同類型的轉換有不同的參數集合,這可能包括轉換完成時變數的值、轉換的持續時間,或基礎數學函數特有的數量,例如加速或振蕩範圍。
所有轉換都會共用兩個隱含參數:數學函式的初始值和初始速度(斜率)。 這些可由應用程式明確指定,但通常會由動畫管理員設定為轉換開始時動畫變數的值和速度。
過渡庫
過渡效果庫目前提供以下過渡效果。 如果應用程式需要無法使用轉換連結庫指定的效果,開發人員可以實作應用程式的自定義插補器,或使用第三方轉換連結庫來建立其他類型的轉換。
轉換名稱 | 描述 |
---|---|
加速減速 |
動畫變數會加快速度,然後在指定的持續時間內變慢。 |
常數 |
在整個轉換期間,動畫變數會維持在其初始值。 |
立方 |
動畫變數會從其初始值變更為指定的最終值,在指定的持續時間內具有指定的最終速度。 |
離散 |
動畫變數會維持在指定延遲時間的初始值,然後立即切換至指定的最終值,並在指定的保留時間維持在該值。 |
瞬間的 |
動畫變數會立即從目前的值變更為指定的最終值。 |
線性 |
動畫變數會以線性方式從其初始值轉換至指定期間內指定的最終值。 |
從速度線性 |
動畫變數會以線性方式從其初始值轉換為具有指定速度的指定最終值。 |
由加速度形成的拋物線 |
動畫變數會從其初始值轉換為指定的最終值,具有指定的最終速度,以指定的加速來變更其速度。 |
逆轉 |
給定時間範圍內的變數會改變方向。 最終值會與初始值相同,而最終速度將是初始速度的負數。 |
範圍中正弦數 |
變數在指定的值範圍內振盪,具有特定的振盪週期,持續指定的時間段。 |
從速度生成的正弦波 |
在指定的持續時間內,變數會以指定的振蕩的周期振蕩。 振蕩的幅度取決於變數的初始速度。 |
平滑停止 |
動畫變數會在最大持續時間內,在指定的最終值上順利停止。 |
下表包含每個轉換的圖例。
插圖 |
---|
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() |
![]() ![]() ![]() |
![]() |
自訂轉換
插補器會定義數學函式,以決定動畫變數在從初始值到最終值時如何隨著時間變化。 轉換庫中的每個轉換都有一個相關的插補器物件,由系統提供並實作插補函式。 如果應用程式需要無法使用轉場庫指定的效果,則可以針對每個新的轉換實作插值器物件,以便實作一個或多個自定義轉換。 插補器物件不能由應用程式直接使用,而是必須封裝在相關聯的過渡效果中。 轉換處理站可用來從插補器對象產生轉換。 如需詳細資訊,請參閱 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。您可以通過調用IUIAnimationStoryboard::AddKeyframeAtOffset 方法,使用UI_ANIMATION_KEYFRAME_STORYBOARD_START來在從開頭的位移增加新關鍵影格。
您新增關鍵影格的位移一律相對於另一個關鍵影格。 下圖顯示了新增 keyframe1 和轉換 T4 的結果。該轉換會套用至變數 Z,與 keyframe1 對齊,並且以固定的持續時間進行創建。 當然,由於還不清楚其他轉換的持續時間,T4 可能不是最後一次轉換完成。
使用 IUIAnimationStoryboard::AddKeyframeAfterTransition 方法,關鍵影格也可以放在轉換過程的末端。 下圖顯示了在 T1 後新增 keyframe2 和在 T2 後新增 keyframe3 的結果。
因為 T1 和 T2 的持續時間在分鏡腳本播放之前是未知的,因此 keyframe2 和 keyframe3 的偏移量也只能到那時才能確定。 因此,keyframe2 甚至可能早於 keyframe1,而 keyframe3 也可能更早發生。
轉換的開始和結尾都可以使用 IUIAnimationStoryboard::AddTransitionBetweenKeyframes 方法,與關鍵影格對齊。 下圖顯示在關鍵影格2與關鍵影格3之間,於變數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 開始時有不同的值。