Windows アプリ用の接続型アニメーション

接続型アニメーションを使用すると、2 つの異なるビューの間で要素が切り替わる様子をアニメーション化することによって、動的で魅力的なナビゲーション エクスペリエンスを作成できます。 これにより、ユーザーはコンテキストを維持して、ビューの間の継続性を実現することができます。

接続型アニメーションでは、UI コンテンツが変化するとき (画面間を移動して、ソース ビュー内の要素の場所から新しいビュー内の切り替え先となる場所が表示されるとき)、要素が 2 つのビューの間で "途切れることなく" 表示されます。 これにより、ビューの間で共通するコンテンツが強調され、要素が切り替わるときに魅力的で動的な効果が発生します。

重要な API: ConnectedAnimation classConnectedAnimationService class

WinUI 2 ギャラリー
WinUI ギャラリー

WinUI 2 ギャラリー アプリがインストールされている場合は、ここをクリックしてアプリを開き、「接続されたアニメーションの動作」を参照してください

この短い動画では、アプリは接続型アニメーションを使用して項目の画像をアニメーション化し、その画像が "途切れることなく" 切り替わり、次のページにあるヘッダーの一部となります。 この効果を利用すると、画面の切り替えでユーザー コンテキストを維持することができます。

接続されたアニメーション

接続型アニメーションと Fluent Design System

Fluent Design System では、ライト、深度、モーション、マテリアル、スケールを取り入れた、モダンで目を引く UI を作成できます。 接続型アニメーションは、アプリに動きを加える Fluent Design System コンポーネントです。 詳しくは、Fluent Design の概要に関するページをご覧ください。

接続型アニメーションを使用する理由

ページ間を移動するときには、移動後にどのような新しいコンテンツが表示されるか、その新しいコンテンツがページを移動するユーザーの目的とどのように関連しているかを、ユーザーが理解できるようにすることが重要です。 接続型アニメーションを利用すると、2 つのビューで共有されているコンテンツにユーザーを注目させることによって、2 つのビューの間の関係を強調する強力な視覚的メタファが実現されます。 また、接続型アニメーションによって、ページを移動するときに、視覚的に注目を引く効果や洗練された視覚効果を発生させることができます。このことは、アプリのモーション デザインを特徴付ける際に役立ちます。

接続型アニメーションを使用するタイミング

一般に、接続型アニメーションはページを変更するとき使用されます。ただし、UI のコンテンツを変更するときに、そのコンテンツが維持されるようにユーザーに対して表示する必要がある場合は、接続型アニメーションをどのようなエクスペリエンスにでも適用できます。 ソース ビューと切り替え先のビューの間で UI の画像や他の UI の要素が共有されている場合は、必ず、ドリル インによるナビゲーション切り替えではなく、接続型アニメーションの使用を検討してください。

接続型アニメーションの構成

重要

この機能を使用するには、アプリのターゲット バージョンが Windows 10 Version 1809 (SDK 17763) 以降である必要があります。 Configuration プロパティは、以前の SDK では使用できません。 アダプティブ コードまたは条件付き XAML を使用して、SDK 17763 より低い最小バージョンを対象にすることができます。 詳しくは、バージョン アダプティブ アプリに関する記事をご覧ください。

Windows 10 Version 1809 以降では、接続型アニメーションは、順方向および逆方向のページ ナビゲーション専用に調整されたアニメーション構成を提供することで、Fluent Design をさらに具体化します。

アニメーション構成を指定するには、ConnectedAnimation の Configuration プロパティを設定します。 (この例は、次のセクションで示します。)

この表では、使用可能な構成について説明します。 これらのアニメーションで適用されるモーション原則の詳細については、「方向性と重力」を参照してください。

GravityConnectedAnimationConfiguration
これは既定の構成であり、順方向ナビゲーションに推奨されます。
ユーザーがアプリ内で順方向 (A から B) に進むと、接続型の要素は物理的に "ページをめくる" ように見えます。 このようにすると、要素は z 空間で順方向に移動するように見え、重力がかかった効果として少しだけ下がります。 重力の効果を克服するために、要素はスピードを上げ、最終的な位置まで加速します。 結果は "スケールと沈下" のアニメーションになります。
DirectConnectedAnimationConfiguration
ユーザーがアプリ内で逆方向 (B から A) に移動すると、アニメーションはより直接的になります。 接続型の要素は、減速の 3 次ベジエ イージング関数を使用して B から A に線形に移動します。 逆方向の視覚的アフォーダンスは、ナビゲーション フローのコンテキストを維持したまま、できるだけ高速にユーザーを前の状態に戻します。
BasicConnectedAnimationConfiguration
これは、Windows 10 Version 1809 (SDK 17763) より前のバージョンで使用されている既定の (かつ唯一の) アニメーションです。

ConnectedAnimationService 構成

ConnectedAnimationService クラスには、サービス全体ではなく個々のアニメーションに適用される 2 つのプロパティがあります。

さまざまな効果を実現するために、一部の構成では、この表で説明するように、ConnectedAnimationService でこれらのプロパティを無視し、代わりに独自の値を使用します。

構成 DefaultDuration を適用? DefaultEasingFunction を適用?
重力 はい はい*
*A から B への基本的な移動では、このイージング関数を使用しますが、"重力沈下" には独自のイージング関数があります。
直接 No
150ms を超えてアニメーション化します。
No
減速のイージング関数を使用します。
Basic はい はい

接続型アニメーションを実装する方法

接続型アニメーションのセットアップでは、次の 2 つの手順を実行します。

  1. ソース ページでアニメーション オブジェクトを "準備" します。この手順では、ソース要素が接続型アニメーションに参加することを、システムに伝えます。
  2. 切り替え先のページでアニメーションを "開始" します。この手順では、切り替え先の要素に参照を渡します。

ソース ページから移動する場合は、ConnectedAnimationService.GetForCurrentView を呼び出して、ConnectedAnimationService のインスタンスを取得します。 アニメーションを準備するには、このインスタンスの PrepareToAnimate を呼び出し、切り替えで使用する一意のキーと UI 要素を渡します。 一意のキーを使用すると、後ほど切り替え先ページでアニメーションを取得できます。

ConnectedAnimationService.GetForCurrentView()
    .PrepareToAnimate("forwardAnimation", SourceImage);

ナビゲーションが発生したら、切り替え先ページでアニメーションを開始します。 アニメーションを開始するには、ConnectedAnimation.TryStart を呼び出します。 アニメーションの作成時に指定した一意のキーを使用して ConnectedAnimationService.GetAnimation を呼び出すことにより、適切なアニメーションのインスタンスを取得できます。

ConnectedAnimation animation =
    ConnectedAnimationService.GetForCurrentView().GetAnimation("forwardAnimation");
if (animation != null)
{
    animation.TryStart(DestinationImage);
}

順方向ナビゲーション

この例では、ConnectedAnimationService を使用して、2 つのページ間の順方向ナビゲーション (Page_A から Page_B) の切り替えを作成する方法を示します。

順方向ナビゲーションの推奨されるアニメーション構成は GravityConnectedAnimationConfiguration です。 これは既定値であるため、別の構成を指定する場合を除き、Configuration プロパティを設定する必要はありません。

ソース ページでアニメーションを設定します。

<!-- Page_A.xaml -->

<Image x:Name="SourceImage"
       HorizontalAlignment="Left" VerticalAlignment="Top"
       Width="200" Height="200"
       Stretch="Fill"
       Source="Assets/StoreLogo.png"
       PointerPressed="SourceImage_PointerPressed"/>
// Page_A.xaml.cs

private void SourceImage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    // Navigate to detail page.
    // Suppress the default animation to avoid conflict with the connected animation.
    Frame.Navigate(typeof(Page_B), null, new SuppressNavigationTransitionInfo());
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    ConnectedAnimationService.GetForCurrentView()
        .PrepareToAnimate("forwardAnimation", SourceImage);
    // You don't need to explicitly set the Configuration property because
    // the recommended Gravity configuration is default.
    // For custom animation, use:
    // animation.Configuration = new BasicConnectedAnimationConfiguration();
}

切り替え先ページでアニメーションを開始します。

<!-- Page_B.xaml -->

<Image x:Name="DestinationImage"
       Width="400" Height="400"
       Stretch="Fill"
       Source="Assets/StoreLogo.png" />
// Page_B.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ConnectedAnimation animation =
        ConnectedAnimationService.GetForCurrentView().GetAnimation("forwardAnimation");
    if (animation != null)
    {
        animation.TryStart(DestinationImage);
    }
}

戻るナビゲーション

戻るナビゲーション (Page_B から Page_A) の場合は、同じ手順に従いますが、ソースと切り替え先のページは逆になります。

ユーザーは戻る移動をしたときに、できるだけ早く以前の状態に戻ることをアプリに期待します。 そのため、推奨される構成は、DirectConnectedAnimationConfiguration です。 このアニメーションはより迅速で直接的であり、減速のイージングを使用します。

ソース ページでアニメーションを設定します。

// Page_B.xaml.cs

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (e.NavigationMode == NavigationMode.Back)
    {
        ConnectedAnimation animation = 
            ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("backAnimation", DestinationImage);

        // Use the recommended configuration for back animation.
        animation.Configuration = new DirectConnectedAnimationConfiguration();
    }
}

切り替え先ページでアニメーションを開始します。

// Page_A.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ConnectedAnimation animation =
        ConnectedAnimationService.GetForCurrentView().GetAnimation("backAnimation");
    if (animation != null)
    {
        animation.TryStart(SourceImage);
    }
}

アニメーションが設定された時点から開始されるまで、ソース要素はアプリ内の他の UI の上に固定された状態で表示されます。 これにより、他の切り替えアニメーションを同時に実行できます。 このため、2 つの手順の間の待機時間は 250 ミリ秒を超えないようにしてください。これを超えると、ソース要素が存在することで問題が発生する可能性があります。 アニメーションを準備しても、アニメーションを 3 秒以内に開始しないと、システムによってアニメーションが破棄され、後続の TryStart の呼び出しは失敗します。

リスト エクスペリエンスとグリッド エクスペリエンスでの接続型アニメーション

多くの場合、リスト コントロールやグリッド コントロール間の切り替えで接続型アニメーションの作成が必要になります。 ListViewGridView の 2 つのメソッドである PrepareConnectedAnimationTryStartConnectedAnimationAsync を使用して、このプロセスを簡略化できます。

たとえば、データ テンプレート内に "PortraitEllipse" という名前の要素を含んでいる ListView があるとします。

<ListView x:Name="ContactsListView" Loaded="ContactsListView_Loaded">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="vm:ContactsItem">
            <Grid>
                …
                <Ellipse x:Name="PortraitEllipse" … />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

指定されたリスト項目に対応する楕円を表示する接続型アニメーションを準備するには、一意のキー、項目、および "PortraitEllipse" という名前を指定して、PrepareConnectedAnimation メソッドを呼び出します。

void PrepareAnimationWithItem(ContactsItem item)
{
     ContactsListView.PrepareConnectedAnimation("portrait", item, "PortraitEllipse");
}

この要素を切り替え先として使用してアニメーションを開始するには (詳細ビューから戻ったときなど)、TryStartConnectedAnimationAsync を使用します。 ListView のデータ ソースが読み込まれると、TryStartConnectedAnimationAsync は、対応する項目コンテナーが作成されるまで、アニメーションが開始されるのを待機します。

private async void ContactsListView_Loaded(object sender, RoutedEventArgs e)
{
    ContactsItem item = GetPersistedItem(); // Get persisted item
    if (item != null)
    {
        ContactsListView.ScrollIntoView(item);
        ConnectedAnimation animation =
            ConnectedAnimationService.GetForCurrentView().GetAnimation("portrait");
        if (animation != null)
        {
            await ContactsListView.TryStartConnectedAnimationAsync(
                animation, item, "PortraitEllipse");
        }
    }
}

連動型アニメーション

調整されたアニメーション

"連動型アニメーション" は特殊な種類の開始アニメーションで、要素が接続型アニメーションのターゲットと共に表示され、接続型アニメーションの要素と連動してアニメーション化され、画面上を横切って移動します。 連動型アニメーションによって、ビューの切り替え時に視覚的にさらに注目を引く効果が発生し、ソース ビューと切り替え先のビューの間で共有されているコンテキストにユーザーを注目させることができます。 上記の画像では、連動型アニメーションを使用して、項目のキャプション UI がアニメーション化されています。

連動型アニメーションで重力構成を使用する場合、接続型アニメーションの要素と連動型の要素の両方に重力が適用されます。 連動型の要素は、接続型の要素と共に "急降下" するので、要素は真に連動した状態になります。

TryStart の 2 つのパラメーター オーバーロードを使用して、連動型の要素を接続型アニメーションに追加します。 次の例では、"DescriptionRoot" という名前のグリッド レイアウトの連動型アニメーションを説明します。このアニメーションは、"CoverImage" という名前の接続型アニメーションの要素と連動して表示されます。

<!-- DestinationPage.xaml -->
<Grid>
    <Image x:Name="CoverImage" />
    <Grid x:Name="DescriptionRoot" />
</Grid>
// DestinationPage.xaml.cs
void OnNavigatedTo(NavigationEventArgs e)
{
    var animationService = ConnectedAnimationService.GetForCurrentView();
    var animation = animationService.GetAnimation("coverImage");

    if (animation != null)
    {
        // Don’t need to capture the return value as we are not scheduling any subsequent
        // animations
        animation.TryStart(CoverImage, new UIElement[] { DescriptionRoot });
     }
}

推奨と非推奨

  • 接続型アニメーションは、ソース ページと切り替え先のページの間で要素が共有されている場合に、ページの切り替えで使用してください。
  • 順方向ナビゲーションには GravityConnectedAnimationConfiguration を使用します。
  • 逆方向ナビゲーションには DirectConnectedAnimationConfiguration を使用します。
  • 接続型アニメーションの準備と開始の間で発生する、ネットワーク要求や他の実行時間の長い非同期操作を待機しないでください。 早めに切り替えを実行するには、必要な情報を事前に読み込んでおく必要があります。または、高解像度の画像が切り替え先のビューに読み込まれるときに、低解像度のプレースホルダー画像を使用する必要があります。
  • ConnectedAnimationService を使用する場合、Frame 内で切り替えアニメーションが使われないようにするには、SuppressNavigationTransitionInfo を使用します。これは、接続型アニメーションが既定のナビゲーション切り替えとは同時に使用できないアニメーションであるためです。 ナビゲーション切り替えの使用方法について詳しくは、「NavigationThemeTransition」をご覧ください。

ConnectedAnimation

ConnectedAnimationService

NavigationThemeTransition