基本的なアニメーション

.NET Multi-Platform App UI (.NET MAUI) アニメーション クラスは、ビジュアル要素のさまざまなプロパティを対象とします。一般的な基本アニメーションでは、一定時間にわたってプロパティをある値から別の値に徐々に変化させます。

基本的なアニメーションは、ViewExtensions クラスによって提供される拡張メソッドを使用して作成できます。これらのアニメーションでは、VisualElement オブジェクトを操作します。

デフォルトでは、各アニメーションには 250 ミリ秒かかります。 ただし、アニメーションを作成するときに、各アニメーションの所要時間を指定できます。

Note

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 秒 (2,000 ミリ秒) で最大 360 度回転します。 RotateTo メソッドは、アニメーションの開始時点における要素の現在の Rotation プロパティ値を取得し、その値から最初の引数 (360) を加えた値まで回転します。 アニメーションが完了すると、画像の Rotation プロパティは 0 にリセットされます。 これにより、アニメーション終了後に Rotation プロパティが 360 のままにならず、追加の回転が阻止されます。

Note

RotateTo メソッドに加えて、RotateXTo メソッドと RotateYTo メソッドもあります。これらのメソッドは、RotationX プロパティと RotationY プロパティをそれぞれアニメーション化します。

相対回転

相対回転は RelRotateTo メソッドで実行され、要素の Rotation プロパティが段階的に変更されます。

await image.RelRotateTo(360, 2000);

この例では、Image インスタンスは開始位置から 2 秒 (2000 ミリ秒) で 360 度回転します。 RelRotateTo メソッドは、アニメーションの開始時の要素の現在の Rotation プロパティ値を取得し、その値から最初の引数 (360) を加えた値まで回転します。 これにより、各アニメーションは、常に開始位置から 360 度回転します。 そのため、アニメーションの進行中に新しいアニメーションが呼び出されると、そのアニメーションは現在の位置から開始され、増分値が 360 度ではない位置で終了する可能性があります。

スケーリング

スケーリングは ScaleTo メソッドで実行され、要素の Scale プロパティが段階的に変更されます。

await image.ScaleTo(2, 2000);

この例では、Image インスタンスが 2 秒 (2000 ミリ秒) で 2 倍のサイズにスケールアップされます。 ScaleTo メソッドは、アニメーションの開始時の要素の現在の Scale プロパティ値を取得し、その値から最初の引数までスケールします。 これは、画像のサイズが 2 倍に拡大される効果があります。

Note

ScaleTo メソッドに加えて、ScaleX プロパティと ScaleY プロパティをそれぞれアニメーション化する ScaleXTo メソッドと ScaleYTo メソッドもあります。

相対スケーリング

相対スケーリングは RelScaleTo メソッドで実行され、要素の Scale プロパティが段階的に変更されます。

await image.RelScaleTo(2, 2000);

この例では、Image インスタンスが 2 秒 (2000 ミリ秒) で 2 倍のサイズにスケールアップされます。 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 単位を上に同時に移動します。 これは、1 番目と 2 番目の引数が両方とも負の数であるためです。 正の数値を指定すると、画像が右および下に移動します。

重要

要素が最初に画面外に配置され、その後画面上に移動した場合、移動後も要素の入力レイアウトは画面外に残り、ユーザーはそれを操作できません。 そのため、ビューを最終的な位置に配置し、必要な移動を実行することをお勧めします。

フェード

フェードは 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 の移動では 5 つのアニメーションが使用され、await 演算子は各アニメーションが順番に実行されることを示します。 そのため、後続のアニメーション メソッドは、前のメソッドが完了した後に実行されます。

複合アニメーション

複合アニメーションは、2 つ以上のアニメーションが同時に実行されるアニメーションの組み合わせです。 複合アニメーションは、待機アニメーションと非待機アニメーションを組み合わせて作成できます。

image.RotateTo(360, 4000);
await image.ScaleTo(2, 2000);
await image.ScaleTo(1, 2000);

この例では、Image インスタンスは 4 秒 (4000 ミリ秒) かけてスケーリングされ、同時に回転されます。 Image のスケーリングには、回転と同時に発生する 2 つの連続アニメーションが使用されます。 RotateTo メソッドは await 演算子なしで実行され、すぐに戻り、最初の ScaleTo アニメーションが始まります。 最初の ScaleTo メソッドの await 演算子は、最初の ScaleTo メソッドが完了するまで 2 番目の ScaleTo メソッドを遅らせます。 この時点で、RotateTo アニメーションは半分完成し、Image は 180 度回転します。 最後の 2 秒 (2000 ミリ秒) の間に、2 番目の 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 メソッドに 2 つのタスクが含まれています。 最初のタスクは Image インスタンスを 4 秒 (4,000 ミリ秒) にわたって回転し、2 番目のタスクは画像を 2 秒 (2,000 ミリ秒) にわたってスケーリングします。 2 番目のタスクが完了すると、Task.WhenAny メソッドの呼び出しが完了します。 ただし、RotateTo メソッドがまだ実行している場合でも、2 番目の 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 メソッドには 3 つのタスクが含まれており、それぞれ 10 分にわたって実行されます。 それぞれの Task は、360 度回転の回数が異なります。RotateTo は 307 回転、RotateXTo は 251 回転、RotateYTo は 199 回転です。 これらの値は素数であるため、回転が同期されることはなく、繰り返しパターンが発生することはありません。

アニメーションのキャンセル

アプリは、CancelAnimations 拡張メソッドを呼び出して 1 つ以上のアニメーションを取り消すことができます。

image.CancelAnimations();

この例では、Image インスタンスで実行されているすべてのアニメーションが直ちに取り消されます。