分鏡腳本概觀

本概觀著重于如何在 Windows 動畫中使用轉換和分鏡腳本。 如需 Windows 動畫元件的概觀,請參閱 Windows 動畫概觀

本主題包含下列幾節:

轉換

轉換會定義單一動畫變數在特定時間間隔中的變更方式。 Windows 動畫包含開發人員可以套用至一或多個動畫變數的通用轉換程式庫。 不同類型的轉換具有不同的參數集合,這可能包括轉換完成時變數的值、轉換的持續時間,或基礎數學函式特有的數量,例如加速或振動範圍。

所有轉換都會共用兩個隱含參數:數學函式的初始值和初始速度 (斜率) 。 這些可由應用程式明確指定,但通常是由動畫管理員設定為轉換開始時動畫變數的值和速度。

轉換程式庫

轉換程式庫目前提供下列轉換。 如果應用程式需要無法使用轉換程式庫指定的效果,開發人員可以實作應用程式的自訂插補器,或使用協力廠商轉換程式庫來建立其他類型的轉換。

轉換名稱 Description
加速減速
動畫變數會加速,然後在指定的持續時間內變慢。
常數
動畫變數在整個轉換期間會維持在其初始值。
三次方
動畫變數會從其初始值變更為指定的最終值,在指定的持續時間內具有指定的最終速度。
離散
動畫變數會維持在指定延遲時間的初始值,然後立即切換至指定的最終值,並保留指定保留時間的該值。
暫態
動畫變數會立即從目前的值變更為指定的最終值。
linear
動畫變數會以線性方式,從其初始值轉換為指定持續時間內的指定最終值。
從速度線性
動畫變數會以線性方式從其初始值轉換為具有指定速度的指定最終值。
加速的雙曲
動畫變數會從其初始值轉換為指定的最終值,並具有指定的最終速度,以指定的加速變更其速度。
逆轉
變數會變更指定持續時間的方向。 最終值會與初始值相同,而最終速度將會是初始速度的負數。
從範圍算起的 sinusoidal
變數在指定的值範圍內,在指定的持續時間內,具有指定的振動期間。
速度的 sinusoidal
變數在指定的持續時間內,會以指定的振動期間來旋轉。 變動的幅度取決於變數的初始速度。
平滑停駐點
動畫變數會在指定的最後一個值到達一個平滑停駐點,時間上限。

下表包含每個轉換的圖例。

插圖
從離散轉換速度圖例之線性轉換圖例的即時轉換圖例的立即轉換圖例
平滑停止轉換之三次方轉換圖的加速圖解的雙曲轉換圖例的圖例
從範圍中正弦轉換的速度圖例反轉轉換圖例的圖例
遞減和減速轉換的圖例

自訂轉換

插補器會定義數學函式,決定動畫變數在從初始值進展到最終值時,動畫變數如何隨著時間變更。 轉換程式庫中的每個轉換都有相關聯的插補器物件,由系統提供並實作插補器函式。 如果應用程式需要無法使用轉換程式庫指定的效果,它可以實作一或多個自訂轉換,方法是為每個新的轉換實作插補點物件。 插補器物件無法由應用程式直接使用,而且必須改為包裝在相關聯的轉換中。 轉換處理站可用來從插補器物件產生轉換。 如需詳細資訊,請參閱 IUIAnimationInterpolatorIUIAnimationTransitionFactory

請注意,大部分的應用程式都會有使用轉換程式庫所需的所有轉換,因此不需要實作插補器。

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 方法。

使用Context-Sensitive持續時間

雖然某些轉換的持續時間固定,但其他轉換的持續時間取決於轉換開始時動畫變數的初始值或速度。 例如, IUIAnimationTransitionLibrary::CreateLinearTransitionFromSpeed 方法會建立與動畫變數初始值與指定最終值之間差異成正比的轉換。 在此圖例中,以及其餘的圖例,會以問號 (?) 來顯示這類具有任意持續時間的轉換,並在腳本播放時決定其實際持續時間。

顯示具有未知持續時間之簡單分鏡腳本的圖例

建置更複雜的分鏡腳本

建立分鏡腳本並新增單一轉換之後,您可以再次呼叫 IUIAnimationStoryboard::AddTransition 方法,而不是 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 方法與主要畫面格對齊。 下圖顯示在 keyframe2 與 keyframe3 之間,于變數 Y 上新增第五個轉換 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,而且只能防止失敗。
  • 任何分鏡腳本都可以壓縮任何其他分鏡腳本, (壓縮一律只會完成,以防止失敗) 。

注意

限定詞「僅防止失敗」表示只有在 UI_ANIMATION_PRIORITY_EFFECT_FAILURE priorityEffect 參數時,已註冊的優先順序比較才會傳回 S_OK。 如需詳細資訊,請參閱 IUIAnimationPriorityComparison::HasPriority 方法。

若要在經過最長可接受的延遲之前啟動 G,動畫管理員必須執行下列動作:

  • 修剪 F
  • 取消 E

取消 E 時,會發現 D 和 F 並還原成其原始大綱:

顯示原始外框的圖例

動畫管理員不需要取消或修剪 C,以在經過最長的可接受延遲之前排程,因此 C 和 G 的會議會決定 G 何時開始。

此圖顯示已修剪 f 以允許 c 和 g 符合

成功排程 G 之後,即可判斷其轉換的持續時間,因此已知其外框的其餘部分。 不過,如果後續從排程中移除另一個分鏡腳本,大綱可能會變更。

作為第二個範例,請考慮上述案例,但為 G 指定的延遲時間較短。

顯示上一個案例的圖例,但 g 的延遲時間較短

在此情況下,會採取下列動作:

  • 修剪 F
  • 取消 E
  • 取消 C

此外,動畫管理員必須壓縮顯示的數量 D,讓 G 在最長可接受延遲之後啟動,且之後再不壓縮。

圖例顯示 d 必須壓縮的位置,才能讓 g 以最長可接受的延遲開始

為了保留其相對時間,也會壓縮 A、B 和 F。

顯示 a、b、d 和 f 壓縮的圖例

不過,不會壓縮不相關的變數上的分鏡腳本, (不會壓縮) 。

同樣地,G 的大綱現在已知,而且與第一個案例的結果不同,因為當 G 開始時,變數有不同的值。

IUIAnimationManager

IUIAnimationPriorityComparison

IUIAnimationStoryboard

IUIAnimationTransitionLibrary