Windows 앱용 연결된 애니메이션

연결된 애니메이션을 사용하면 두 가지 보기 간에 전환되는 동작에 애니메이션 효과를 적용하여 역동적이고 매력적인 탐색 환경을 만들 수 있습니다. 이렇게 하면 사용자가 컨텍스트를 유지하는 데 도움이 될 뿐 아니라 보기 간에 연속성이 보장됩니다.

연결된 애니메이션에서는 UI 콘텐츠가 바뀌는 동안 요소가 두 보기 간에 "계속 있는" 것처럼 보이고, 원본 보기의 원래 위치에서 새 보기의 대상 위치로 화면을 가로질러 날아갑니다. 이렇게 하면 보기 간의 공통 콘텐츠가 강조되며 전환 시 아름답고 역동적인 효과를 얻을 수 있습니다.

중요 API: ConnectedAnimation 클래스, ConnectedAnimationService 클래스

예제

WinUI 2 갤러리
WinUI Gallery

WinUI 2 Gallery 앱이 설치된 경우 여기를 클릭하여 앱을 열고 작동 중인 연결된 애니메이션을 확인합니다.

이 짧은 동영상에 나오는 앱에서는 항목 이미지가 "계속해서" 다음 페이지의 머리글이 되도록 연결된 애니메이션을 사용하여 항목 이미지에 애니메이션 효과를 줍니다. 이 효과는 전환 시 사용자 컨텍스트를 유지하는 데 도움이 됩니다.

Connected Animation

연결된 애니메이션 및 Fluent Design 시스템

Fluent 디자인 시스템을 사용하면 조명, 깊이, 움직임, 재질 및 배율이 통합된 선명한 현대식 UI를 만들 수 있습니다. 연결된 애니메이션은 앱에 동작을 추가하는 Fluent Design 시스템 구성 요소입니다. 자세한 내용은 Fluent Design 개요를 참조하세요.

연결된 애니메이션을 사용하는 이유

페이지를 탐색할 때 사용자는 탐색 후 어떤 새 콘텐츠가 제공되며 탐색할 때 해당 콘텐츠가 사용자의 의도와 어떤 관계가 있는지 이해할 수 있어야 합니다. 연결된 애니메이션은 두 보기 간에 공유되는 콘텐츠에 사용자의 포커스를 그려서 두 보기 간의 관계를 강조함으로써 강력한 시각적 비유를 제공합니다. 뿐만 아니라 연결된 애니메이션은 페이지 탐색에 앱의 동작 디자인을 차별화하는 시각적 흥미와 세련미를 더해 줍니다.

연결된 애니메이션을 사용하는 시기

연결된 애니메이션은 UI의 콘텐츠를 변경하고 사용자로 하여금 컨텍스트를 유지하게 하려는 모든 환경에 적용할 수 있지만 일반적으로 페이지를 변경할 때 사용됩니다. 원본 보기와 대상 보기 사이에 공유되는 이미지 또는 기타 UI 부분이 있을 때에는 드릴인 탐색 전환 대신 연결된 애니메이션을 사용하는 방안을 고려해야 합니다.

연결된 애니메이션 구성

Important

이 기능을 사용하려면 앱의 대상 버전이 Windows 10, 버전 1809(SDK 17763) 이상이어야 합니다. Configuration 속성은 이전 SDK에서 사용할 수 없습니다. 적응 코드 또는 조건부 XAML을 사용하여 SDK 17763보다 낮은 최소 버전을 대상으로 지정할 수 있습니다. 자세한 내용은 버전 적응형 앱을 참조하세요.

Windows 10 버전 1809부터 연결된 애니메이션은 앞으로 및 뒤로 페이지 탐색을 위해 특별히 맞춤화된 애니메이션 구성을 제공하여 Fluent 디자인을 더욱 구체화합니다.

ConnectedAnimation에서 Configuration 속성을 설정하여 애니메이션 구성을 지정합니다. (다음 섹션에서 이에 대한 예를 확인할 수 있습니다.)

이 표에서는 사용 가능한 구성에 대해 설명합니다. 이 애니메이션에 적용된 동작 원리에 대한 자세한 내용은 방향 및 중력을 참조하세요.

GravityConnectedAnimationConfiguration
이것이 기본 구성이며 앞으로 탐색에 권장됩니다.
사용자가 앱에서 앞으로(A에서 B로) 탐색할 때 연결된 요소는 물리적으로 "페이지를 끌어오는" 것처럼 보입니다. 그렇게 하면 요소가 z 공간에서 앞으로 이동하는 것처럼 보이며 중력이 유지되는 효과로 약간 떨어집니다. 중력의 영향을 극복하기 위해 요소는 속도를 얻고 최종 위치로 가속됩니다. 결과는 "스케일 및 딥 애니메이션입니다.
DirectConnectedAnimationConfiguration
사용자가 앱에서 뒤로(B에서 A로) 탐색하면 애니메이션이 더 직접적입니다. 연결된 요소는 감속 3차원 감속/가속 함수를 사용하여 B에서 A로 선형 변환합니다. 역방향 시각적 어포던스는 탐색 흐름의 컨텍스트를 유지하면서 가능한 한 빨리 사용자를 이전 상태로 되돌립니다.
BasicConnectedAnimationConfiguration
이는 Windows 10, 버전 1809(SDK 17763) 이전 버전에서 사용된 기본(유일한) 애니메이션입니다.

ConnectedAnimationService configuration

ConnectedAnimationService 클래스에는 전체 서비스가 아닌 개별 애니메이션에 적용되는 두 가지 속성이 있습니다.

다양한 효과를 가져오기 위해 일부 구성은 ConnectedAnimationService에서 이러한 속성을 무시하고 이 표에 설명된 대로 대신 자체 값을 사용합니다.

구성 DefaultDuration을 고려하나요? DefaultEasingFunction을 고려하나요?
Gravity 예*
*A에서 B로의 기본 변환은 이 감속/가속 함수를 사용하지만 "중력 강하"에는 자체 감속/가속 함수가 있습니다.
Direct 아님
150ms 이상 애니메이션.
아님
감속/가속 함수를 사용합니다.
기본

연결된 애니메이션을 구현하는 방법

연결된 애니메이션을 설정하려면 다음 두 단계를 거쳐야 합니다.

  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를 사용하여 두 페이지(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 위에 고정된 것처럼 보입니다. 이를 통해 다른 전환 애니메이션을 동시에 수행할 수 있습니다. 이러한 이유로 원본 요소가 있으면 주의가 산만해질 수 있으므로 두 단계 사이에 기다리는 시간이 250밀리초를 넘으면 안 됩니다. 애니메이션을 준비하고 3초 이내에 시작하지 않으면 시스템에서 애니메이션을 삭제하고 후속 TryStart 호출이 실패합니다.

목록 및 그리드 환경의 연결된 애니메이션

목록 또는 그리드 컨트롤에서/로 연결된 애니메이션을 만들고 싶은 경우가 종종 있을 것입니다. 두 가지 메서드 ListViewGridViewPrepareConnectedAnimationTryStartConnectedAnimationAsync를 사용하여 이 프로세스를 간소화할 수 있습니다.

예를 들어 데이터 템플릿에 "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");
        }
    }
}

조정된 애니메이션

Coordinated Animation

조정된 애니메이션은 연결된 애니메이션 대상과 함께 요소가 표시되는 특수한 종류의 입구 애니메이션으로, 화면을 넘어갈 때 연결된 애니메이션 요소와 함께 애니메이션 효과를 줍니다. 조정된 애니메이션은 전환에 더 많은 시각 효과를 추가하여 원본 보기와 대상 보기 사이에 공유되는 상황에 대해 사용자의 관심을 더 많이 끌 수 있습니다. 다음 그림에서 항목의 UI는 조정된 애니메이션을 사용하여 애니메이션 효과를 적용합니다.

조정 애니메이션이 중력 구성을 사용하는 경우 연결된 애니메이션 요소와 조정 요소 모두에 중력이 적용됩니다. 조정된 요소는 연결된 요소와 함께 "급습"하여 요소가 진정으로 조정된 상태를 유지합니다.

TryStart의 2-매개 변수 오버로드를 사용하여 연결된 애니메이션에 조정된 요소를 추가합니다. 이 예에서는 "CoverImage"라는 연결된 애니메이션 요소와 함께 입력되는 "DescriptionRoot"라는 그리드 레이아웃의 조정된 애니메이션을 보여 줍니다.

<!-- 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를 사용하는 경우 SuppressNavigationTransitionInfo를 사용하여 Frame에서 전환 애니메이션을 차단해야 합니다. 탐색 전환을 사용하는 방법에 대한 자세한 내용은 NavigationThemeTransition을 참조하세요.

ConnectedAnimation

ConnectedAnimationService

NavigationThemeTransition