カスタム アニメーション
.NET マルチプラットフォーム アプリ UI (.NET MAUI) Animation クラスは、すべての .NET MAUI アニメーションの構成要素であり、ViewExtensions クラスの拡張メソッドによって 1 つ以上の Animation オブジェクトが作成されます。
Animation オブジェクトを作成するときは、アニメーション化するプロパティの開始値と終了値、プロパティの値を変更するコールバックなど、多数のパラメーターを指定する必要があります。 Animation オブジェクトは、実行および同期できる子アニメーションのコレクションを維持することもできます。 詳細については、「子アニメーション」をご覧ください。
Animation クラスで作成されたアニメーション(子アニメーションが含まれる場合と含まれない場合があります)を実行するには、Commit メソッドを呼び出します。 このメソッドはアニメーションの継続時間を指定し、特にアニメーションを繰り返すかどうかを制御するコールバックを指定します。
Note
Animation クラスには IsEnabled プロパティがあり、省電力モードが有効になっている場合など、オペレーティング システムによってアニメーションが無効にされているかどうかを調べることができます。
Android では、アニメーションはシステム アニメーションの設定を考慮します。
- システムのアニメーションが (アクセシビリティ機能または開発者機能によって) 無効になっている場合、新しいアニメーションはすぐに終了状態にジャンプします。
- アニメーションの進行中にデバイスの省電力モードがアクティブになると、アニメーションはすぐに終了状態にジャンプします。
- アニメーションの進行中にデバイスのアニメーション期間がゼロ (無効) に設定されており、API バージョンが 33 以上の場合、アニメーションはすぐに終了状態にジャンプします。
アニメーションを作成する
Animation オブジェクトを作成する場合、次のコード例に示すように、通常は少なくとも 3 つのパラメーターが必要です。
var animation = new Animation(v => image.Scale = v, 1, 2);
この例では、Image インスタンスの Scale プロパティのアニメーションは、値 1 から値 2 まで定義されています。 アニメーション値は最初の引数として指定されたコールバックに渡され、Scale プロパティの値を変更するために使用されます。
アニメーションは、Commit メソッドの呼び出しで開始されます:
animation.Commit(this, "SimpleAnimation", 16, 2000, Easing.Linear, (v, c) => image.Scale = 1, () => true);
Note
Commit メソッドは、Task
オブジェクトを返しません。 代わりに、通知はコールバック メソッドを介して提供されます。
次の引数は Commit メソッドで指定されます。
- 最初の引数 (
owner
) はアニメーションの所有者を識別します。 これは、アニメーションが適用される視覚要素、またはページなどの別の視覚要素にすることができます。 - 2 番目の引数 (
name
) は、アニメーションを名前で識別します。 名前は所有者と組み合わせて、アニメーションを一意に識別します。 その後、この一意の ID を使用して、アニメーションが実行中かどうかを判断したり (AnimationIsRunning)、アニメーションをキャンセルしたり (AbortAnimation) できます。 - 3 番目の引数 (
rate
) は、Animation コンストラクターで定義されたコールバック メソッドの各呼び出し間のミリ秒数を示します。 - 4 番目の引数 (
length
) は、アニメーションの継続時間をミリ秒単位で示します。 - 5 番目の引数 (Easing) は、アニメーションで使用されるイージング関数を定義します。 あるいは、イージング関数を Animation コンストラクターへの引数として指定することもできます。 イージング関数の詳細については、「イージング関数」をご覧ください。
- 6 番目の引数 (
finished
) は、アニメーションが完了したときに実行されるコールバックです。 このコールバックは 2 つの引数を取ります。最初の引数は最終値を示し、2 番目の引数はアニメーションがキャンセルされた場合にtrue
に設定されるbool
です。 または、finished
コールバックを Animation コンストラクターへの引数として指定することもできます。 ただし、1 つのアニメーションの場合、finished
コールバックが Animation コンストラクタと Commit メソッドの両方で指定されている場合、Commit メソッドで指定されたコールバックのみが実行されます。 - 7 番目の引数 (
repeat
) は、アニメーションを繰り返し実行できるようにするコールバックです。 これはアニメーションの最後に呼び出され、true
を返すとアニメーションを繰り返す必要があることを示します。
上記の例では、全体的な効果は、Linear イージング関数を使用して、Image インスタンスの Scale プロパティを 2 秒 (2000 ミリ秒) かけて 1 から 2 に増加させるアニメーションを作成することです。 アニメーションが完了するたびに、その Scale プロパティは 1 にリセットされ、アニメーションが繰り返されます。
子アニメーション
Animation クラスは、他の Animation オブジェクトが子として追加される Animation オブジェクトである子アニメーションもサポートします。 これにより、一連のアニメーションを実行して同期できるようになります。 次のコード例は、子アニメーションの作成と実行を示しています。
var parentAnimation = new Animation();
var scaleUpAnimation = new Animation(v => image.Scale = v, 1, 2, Easing.SpringIn);
var rotateAnimation = new Animation(v => image.Rotation = v, 0, 360);
var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SpringOut);
parentAnimation.Add(0, 0.5, scaleUpAnimation);
parentAnimation.Add(0, 1, rotateAnimation);
parentAnimation.Add(0.5, 1, scaleDownAnimation);
parentAnimation.Commit(this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState(true, false));
あるいは、コード例をより簡潔に記述することもできます。
new Animation
{
{ 0, 0.5, new Animation (v => image.Scale = v, 1, 2) },
{ 0, 1, new Animation (v => image.Rotation = v, 0, 360) },
{ 0.5, 1, new Animation (v => image.Scale = v, 2, 1) }
}.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));
どちらの例でも、親 Animation オブジェクトが作成され、その後、追加の Animation オブジェクトが追加されます。 Add メソッドの最初の 2 つの引数は、子アニメーションを開始および終了するタイミングを指定します。 引数の値は 0 から 1 の間である必要があり、指定された子アニメーションがアクティブになる親アニメーション内の相対的な期間を表します。 したがって、この例では、scaleUpAnimation
はアニメーションの前半でアクティブになり、scaleDownAnimation
はアニメーションの後半でアクティブになり、rotateAnimation
は継続時間全体でアクティブになります。
この例の全体的な効果は、アニメーションが 4 秒 (4000 ミリ秒) にわたって発生することです。 scaleUpAnimation
は、Scale プロパティを 2 秒かけて 1 から 2 までアニメーション化します。 次に、scaleDownAnimation
は、Scale プロパティを 2 から 1 まで 2 秒かけてアニメーション化します。 両方のスケール アニメーションが発生している間、rotateAnimation
は Rotation プロパティを 0 から 360 まで 4 秒間アニメーション化します。 どちらのスケーリング アニメーションもイージング関数を使用します。 SpringIn イージング関数により、Image インスタンスは大きくなる前に最初に縮小され、SpringOut イージング関数により、アニメーション全体の終わりに向けて Image が実際のサイズより小さくなります。
子アニメーションを使用する Animation オブジェクトと、子アニメーションを使用しないオブジェクトの間には、多くの違いがあります。
- 子アニメーションを使用する場合、子アニメーションの
finished
コールバックは子の完了を示し、Commit メソッドに渡されるfinished
コールバックはアニメーション全体の完了を示します。 - 子アニメーションを使用する場合、Commit メソッドの
repeat
コールバックからtrue
を返してもアニメーションは繰り返されませんが、アニメーションは新しい値なしで引き続き実行されます。 - Commit メソッドにイージング関数が含まれており、イージング関数が 1 より大きい値を返した場合、アニメーションは終了します。 イージング関数が 0 未満の値を返す場合、値は 0 に固定されます。 0 未満または 1 より大きい値を返すイージング関数を使用するには、Commit メソッドではなく、いずれかの子アニメーションで指定する必要があります。
Animation クラスには、親 Animation オブジェクトに子アニメーションを追加するために使用できる WithConcurrent メソッドも含まれています。 ただし、begin
と finish
の引数の値は 0 から 1 に制限されず、0 から 1 の範囲に対応する子アニメーションの部分のみがアクティブになります。 たとえば、WithConcurrent メソッド呼び出しが 1 から 6 の Scale プロパティを対象とする子アニメーションを定義するが、begin
と finish
の値が -2 と 3 である場合、begin
値 -2 は Scale 値 1 に対応し、finish
値 3 は Scale 値 6 に対応します。 0 と 1 の範囲外の値はアニメーションに関与しないため、Scale プロパティは 3 から 6 までのみアニメーション化されます。
アニメーションを取り消す
アプリは、AbortAnimation 拡張メソッドを呼び出してカスタム アニメーションを取り消すことができます。
this.AbortAnimation ("SimpleAnimation");
アニメーションはアニメーション所有者とアニメーション名の組み合わせによって一意に識別されるため、アニメーションを取り消すには、アニメーションの実行時に指定された所有者と名前を指定する必要があります。 したがって、この例では、ページが所有する SimpleAnimation
という名前のアニメーションを直ちに取り消します。
カスタム アニメーションを作成する
これまでにここで示した例は、ViewExtensions クラスのメソッドでも同様に実現できるアニメーションを示しています。 ただし、Animation クラスの利点は、アニメーション化された値が変更されたときに実行されるコールバック メソッドにアクセスできることです。 これにより、コールバックは任意のアニメーションを実装できます。 たとえば、次のコード例では、ページの BackgroundColor プロパティを、Color.FromHsla
メソッドで作成された Color 値に設定し、色相の値を 0 から 1 に設定してアニメーション化します。
new Animation (callback: v => BackgroundColor = Color.FromHsla (v, 1, 0.5),
start: 0,
end: 1).Commit (this, "Animation", 16, 4000, Easing.Linear, (v, c) => BackgroundColor = Colors.Black);
結果として得られるアニメーションでは、ページの背景が虹の色で進んでいくように見えます。
カスタム アニメーション拡張メソッドを作成する
ViewExtensions クラスの拡張メソッドは、プロパティを現在の値から指定された値にアニメーション化します。 このため、たとえば、色をある値から別の値にアニメーション化するために使用できる ColorTo
アニメーション メソッドの作成が困難になります。 これは、コントロールによって型 Color のプロパティが異なるためです。 VisualElement クラスは BackgroundColor プロパティを定義しますが、これはアニメーション化するのに望ましい Color
プロパティであるとは限りません。
この問題の解決策は、ColorTo
メソッドで特定の Color
プロパティを対象にしないことです。 代わりに、補間された Color 値を呼び出し元に渡すコールバック メソッドを使用して記述することができます。 さらに、このメソッドは開始と終了の Color 引数を受け取ります。
ColorTo
メソッドは、AnimationExtensions クラスの Animate メソッドを使用してその機能を提供する拡張メソッドとして実装できます。 これは、次のコード例に示すように、Animate メソッドを使用して、型 double
以外のプロパティを対象にできるためです。
public static class ViewExtensions
{
public static Task<bool> ColorTo(this VisualElement self, Color fromColor, Color toColor, Action<Color> callback, uint length = 250, Easing easing = null)
{
Func<double, Color> transform = (t) =>
Color.FromRgba(fromColor.Red + t * (toColor.Red - fromColor.Red),
fromColor.Green + t * (toColor.Green - fromColor.Green),
fromColor.Blue + t * (toColor.Blue - fromColor.Blue),
fromColor.Alpha + t * (toColor.Alpha - fromColor.Alpha));
return ColorAnimation(self, "ColorTo", transform, callback, length, easing);
}
public static void CancelAnimation(this VisualElement self)
{
self.AbortAnimation("ColorTo");
}
static Task<bool> ColorAnimation(VisualElement element, string name, Func<double, Color> transform, Action<Color> callback, uint length, Easing easing)
{
easing = easing ?? Easing.Linear;
var taskCompletionSource = new TaskCompletionSource<bool>();
element.Animate<Color>(name, transform, callback, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
return taskCompletionSource.Task;
}
}
Animate メソッドには、コールバック メソッドである transform
引数が必要です。 このコールバックへの入力は常に 0 から 1 の範囲の double
です。 したがって、この例では、ColorTo
メソッドは、0 から 1 の範囲の double
を受け入れ、その値に対する Color 値を返す独自の変換 Func
を定義します。 Color 値は、指定された 2 つの Color 引数の Red
、Green
、Blue
、Alpha
の値を補間することによって計算されます。 Color 値は、その後コールバック メソッドに渡され、プロパティに適用されます。 この方法により、ColorTo
メソッドで指定された Color プロパティをアニメーション化できます。
await Task.WhenAll(
label.ColorTo(Colors.Red, Colors.Blue, c => label.TextColor = c, 5000),
label.ColorTo(Colors.Blue, Colors.Red, c => label.BackgroundColor = c, 5000));
await this.ColorTo(Color.FromRgb(0, 0, 0), Color.FromRgb(255, 255, 255), c => BackgroundColor = c, 5000);
await boxView.ColorTo(Colors.Blue, Colors.Red, c => boxView.Color = c, 4000);
このコード例では、ColorTo
メソッドは、Label の TextColor
プロパティと BackgroundColor プロパティ、ページの BackgroundColor プロパティ、BoxView の Color
プロパティをアニメーション化します。
.NET MAUI