基本動畫
.NET 多平臺應用程式 UI (.NET MAUI) 動畫類別會以視覺元素的不同屬性為目標,一般的基本動畫會在一段時間內逐漸將屬性從一個值變更為另一個值。
您可以使用 ViewExtensions 類別所提供的擴充方法來建立基本動畫,該方法可在 VisualElement 物件上運作:
- CancelAnimations 取消任何動畫。
- FadeTo 以動畫顯示 VisualElement的 Opacity 屬性。
- RelScaleTo 會以動畫方式漸增或漸減 VisualElement的 Scale 屬性。
- RotateTo 以動畫顯示 VisualElement的 Rotation 屬性。
- RelRotateTo 會將動畫式的逐步增加或減少套用至 VisualElement的 Rotation 屬性。
- RotateXTo 以動畫顯示 VisualElement的 RotationX 屬性。
- RotateYTo 以動畫顯示 VisualElement的 RotationY 屬性。
- ScaleTo 以動畫顯示 VisualElement的 Scale 屬性。
- ScaleXTo 以動畫顯示 VisualElement的 ScaleX 屬性。
- ScaleYTo 以動畫顯示 VisualElement的 ScaleY 屬性。
- TranslateTo 動畫化 VisualElement的 TranslationX 和 TranslationY 屬性。
根據預設,每個動畫將需要 250 毫秒。 不過,建立動畫時可以指定每個動畫的持續時間。
注意
ViewExtensions 類別也提供 LayoutTo 擴充方法。 不過,這個方法是用來讓佈局動畫化在包含大小和位置變更的佈局狀態之間的轉換。
ViewExtensions 類別中的動畫擴充方法都是異步的,並傳回 Task<bool>
物件。 如果動畫完成,則會 false
傳回值,如果取消動畫,則為 true
。 因此,當動畫作業與 await
運算子結合時,就可以使用先前方法完成之後執行的後續動畫方法建立循序動畫。 如需詳細資訊,請參閱 復合動畫。
如果需要讓動畫在背景中完成,則可以省略 await
運算符。 在此情境中,動畫延伸方法會在啟動動畫後快速返回,而動畫則在背景中進行。 建立復合動畫時,可以利用這項作業。 如需詳細資訊,請參閱 複合動畫。
在Android上,動畫會遵守系統動畫設定:
- 如果系統動畫已停用(由輔助功能功能或開發人員功能),新的動畫會立即跳至其完成狀態。
- 如果在動畫進行時啟動裝置的省電模式,動畫會立即跳至其完成狀態。
- 如果裝置的動畫持續時間設定為零(已停用),而動畫正在進行中,且 API 版本為 33 或更新版本,動畫會立即跳至其完成狀態。
單一動畫
ViewExtensions 類別中的每個擴充方法都會實作單一動畫作業,該作業會在一段時間內逐漸將屬性從一個值變更為另一個值。
旋轉
旋轉是使用 RotateTo 方法執行,此方法會逐漸變更元素的 Rotation 屬性。
await image.RotateTo(360, 2000);
image.Rotation = 0;
在此範例中,Image 實例會在 2 秒 (2000 毫秒) 中旋轉高達 360 度。 RotateTo 方法會取得動畫開始時元素的目前 Rotation 屬性值,然後從該值旋轉至其第一個參數(360)。 動畫完成之後,影像的 Rotation 屬性會重設為 0。 這可確保動畫結束之後,Rotation 屬性不會維持在 360,這會防止其他旋轉。
相對旋轉
相對旋轉是使用 RelRotateTo 方法執行,此方法會逐漸變更元素的 Rotation 屬性:
await image.RelRotateTo(360, 2000);
在此範例中,Image 實例會從起始位置旋轉 360 度,超過 2 秒(2000 毫秒)。 RelRotateTo 方法會取得動畫開始元素目前的 Rotation 屬性值,然後從該值旋轉到該值加上其第一個參數(360)的值。 這可確保每個動畫一律會從起始位置旋轉 360 度。 因此,如果在動畫進行中時叫用新的動畫,它會從目前的位置開始,而且可能以非遞增 360 度的位置結束。
縮放
縮放是使用 ScaleTo 方法執行,此方法會逐漸變更元素的 Scale
屬性。
await image.ScaleTo(2, 2000);
在此範例中,Image 實例的大小會在 2 秒內擴大到兩倍(2000 毫秒)。 ScaleTo 方法會取得動畫開始時元素的目前 Scale 屬性值,然後從該值調整為第一個參數。 這會將影像的大小擴充至兩倍。
相對縮放
使用 RelScaleTo 方法執行相對調整,這會逐漸變更元素的 Scale 屬性:
await image.RelScaleTo(2, 2000);
在此範例中,Image 實例的大小會在兩秒內縮放至其原大小的兩倍(2000 毫秒)。 RelScaleTo 方法會取得動畫起始時元素的目前 Scale 屬性值,然後從該值調整為該值加上其第一個參數。 這可確保每個動畫一律會從起始位置開始,按照 2 倍比例縮放。
使用錨點進行縮放和旋轉
視覺元素的 AnchorX
和 AnchorY
屬性會設定 Rotation 和 Scale 屬性的旋轉或縮放中心。 因此,其值也會影響 RotateTo 和 ScaleTo 方法。
假設有一個已放置在版面配置中心的 Image,以下的程式碼範例透過設定其 AnchorY
屬性來示範如何在版面配置中心旋轉圖片:
double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);
若要繞版面配置中心旋轉 Image 實例,AnchorX 和 AnchorY 屬性必須設定為相對於 Image寬度和高度的值。 在此範例中,Image 的中心定義為配置中心,因此預設 AnchorX 值 0.5 不需要變更。 不過,AnchorY 屬性會重新定義為一個從 Image 頂端到佈局中心點的值。 這可確保 Image 能在版面配置中心點周圍完整旋轉 360 度。
翻譯
翻譯是使用 TranslateTo 方法執行,此方法會逐漸變更專案的 TranslationX 和 TranslationY 屬性:
await image.TranslateTo(-100, -100, 1000);
在此範例中,Image 實例會水準和垂直轉譯超過 1 秒(1000 毫秒)。 TranslateTo 方法同時將影像 100 個裝置獨立單位轉譯到左邊,向上轉譯 100 個裝置獨立單位。 這是因為第一個和第二個自變數都是負數。 提供正數會將影像向右和向下移動。
重要
如果元素起初配置在螢幕外,然後移動到螢幕上,那麼在移動後,元素的輸入配置仍然保持在螢幕外,使用者無法與之互動。 因此,建議將視圖配置在其最終位置,然後執行任何必要的轉換。
衰落
使用 FadeTo 方法來淡化,逐漸改變元素的 Opacity 屬性:
image.Opacity = 0;
await image.FadeTo(1, 4000);
在此範例中,Image 實例會在 4 秒(4000 毫秒)內淡出。 FadeTo 方法會在動畫開始時取得元素的目前 Opacity 屬性值,然後從該值淡入到其第一個參數。
合成動畫
復合動畫是動畫的循序組合,可以使用 await
運算符來建立:
await image.TranslateTo(-100, 0, 1000); // Move image left
await image.TranslateTo(-100, -100, 1000); // Move image diagonally up and left
await image.TranslateTo(100, 100, 2000); // Move image diagonally down and right
await image.TranslateTo(0, 100, 1000); // Move image left
await image.TranslateTo(0, 0, 1000); // Move image up
在此範例中,Image 例項會在 6 秒內完成轉譯(6000 毫秒)。
Image 的轉譯會使用五個動畫,而 await
運算符表示每個動畫會循序執行。 因此,後續動畫方法會在上一個方法完成之後執行。
合成動畫
合成動畫是動畫的組合,其中兩個或多個動畫會同時進行。 結合可等待和不可等待的動畫,即可建立複合動畫。
image.RotateTo(360, 4000);
await image.ScaleTo(2, 2000);
await image.ScaleTo(1, 2000);
在此範例中,Image 實例在 4 秒(4000 毫秒)內同步縮放並旋轉。
Image 的縮放會使用兩個與旋轉同時進行的連續動畫。
RotateTo 方法會在沒有 await
運算符的情況下執行,並立即傳回 ,然後開始第一個 ScaleTo 動畫。 第一個 ScaleTo 方法上的 await
運算符會延遲第二個 ScaleTo 方法,直到第一個 ScaleTo 方法完成為止。 此時,RotateTo 動畫已完成一半,Image 將旋轉 180 度。 在最後 2 秒(2000 毫秒)期間,第二個 ScaleTo 動畫和 RotateTo 動畫都已完成。
同時執行多個動畫
Task.WhenAny
和 Task.WhenAll
方法可用來同時執行多個異步方法,因此可以建立復合動畫。 這兩種方法都會傳回 Task
物件,並接受每一個傳回 Task
物件的方法集合。 當集合中的任何方法完成執行時,Task.WhenAny
方法就會完成,如下列程式代碼範例所示:
await Task.WhenAny<bool>
(
image.RotateTo(360, 4000),
image.ScaleTo(2, 2000)
);
await image.ScaleTo(1, 2000);
在此範例中,Task.WhenAny
方法包含兩個工作。 第一個任務會在 4 秒(4000 毫秒)內旋轉 Image 實例,而第二個任務會在 2 秒(2000 毫秒)內縮放影像。 當第二個工作完成時,Task.WhenAny
方法呼叫就會完成。 不過,即使 RotateTo 方法仍在執行中,第二個 ScaleTo 方法還是可以開始。
當集合中的所有方法都完成時,Task.WhenAll
方法就會完成,如下列程式代碼範例所示:
// 10 minute animation
uint duration = 10 * 60 * 1000;
await Task.WhenAll
(
image.RotateTo(307 * 360, duration),
image.RotateXTo(251 * 360, duration),
image.RotateYTo(199 * 360, duration)
);
在此範例中,Task.WhenAll
方法包含三個工作,每個工作執行超過 10 分鐘。 每個 Task
完成的 360 度旋轉次數都不同,RotateTo為 307 次旋轉,RotateXTo為 251 次旋轉,RotateYTo為 199 次旋轉。 這些值是質數,因此可確保旋轉不會同步,從而不會產生重複的模式。
取消動畫
CancelAnimations 擴充方法可用來取消在特定 VisualElement上執行的任何動畫,例如旋轉、縮放、翻譯和淡化。
image.CancelAnimations();
在此範例中,Image 實例上執行的所有動畫都會立即取消。