It's always been tedious in XAML apps to make transitional animations between two pages.

To animate an image between two pages, the navigation system had to be modified to allow these animations.

The anniversary update brings a new medium called connected animations” that makes these animations trivial to make.

Original illustration unavailable: connectedanimation

How does this work?

The ConnectedAnimationService class allows a visual element to be passed between multiple XAML pages.

Let's code together an example to understand how this works.

Master page:


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <GridView x:Name="ItemsGridView"
                Loaded="ItemsGridView_Loaded"
                SelectionMode="None"
                IsItemClickEnabled="True"
                ItemClick="ItemsGridView_ItemClick"
                Margin="50"
                ItemsSource="{x:Bind ViewModel.Items}">


        <GridView.ItemTemplate>
            <DataTemplate x:DataType="data:Thumbnail">
                <Border BorderBrush="Black"
                        BorderThickness="1">
                    <Image x:Name="ImageItem"
                            Width="200"
                            Height="200"
                            Margin="2"
                            Stretch="Uniform"
                            Source="{x:Bind ImageUrl}" />
                </Border>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
</Grid>


private void ItemsGridView_ItemClick(object sender, ItemClickEventArgs e)
{
    var container = ItemsGridView.ContainerFromItem(e.ClickedItem) as GridViewItem;
    if (container != null)
    {
        var root = (FrameworkElement)container.ContentTemplateRoot;
        //Au click sur la gridView
        //Récupération de l'image que l'on veut animer.
        var image = (UIElement)root.FindName("ImageItem");
        //On prépare l'animation
        ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("Image", image);
    }

    var item = (Thumbnail)e.ClickedItem;
    //On navigue vers la page détail : en passant en paramètre l'url de l'image selectionnée
    Frame.Navigate(typeof(ConnectedAnimationDetail), _navigatedUri = item.ImageUrl);
}

Details page:

The code XAML:


<Page x:Class="UWPWhatsNew.Views.ConnectedAnimation.ConnectedAnimationDetail"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:UWPWhatsNew.Views.ConnectedAnimation"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid>
        <Image x:Name="_image"
               Margin="50"
               VerticalAlignment="Center"
               HorizontalAlignment="Center" />
    </Grid>
</Page>

C# code


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e)
    //Récupération du paramètre passé lors de la navigation
    _image.Source = new BitmapImage(new Uri((string)e.Parameter));
    //On récupére l'animation ayant comme nom Image.
    var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("Image");
    if (animation != null)
    {
        _image.Opacity = 0;
        //On lance l'animation uniquement quand l'image est chargée
        _image.ImageOpened += (sender_, e_) =>
        {
            animation.TryStart(_image);
        };
    }
    //On s'abonne à l'évènement back de la page, comme ça l'utilisateur clickera sur back on rejouera l'animation dans l'autre sens
    _systemNavigationManager.BackRequested += ConnectedAnimationDetail_BackRequested;
    _systemNavigationManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
}

When the user clicks back the animation is prepared so that the master page can play the animation.


private void ConnectedAnimationDetail_BackRequested(object sender, BackRequestedEventArgs e)
{
    if (e.Handled)
    {
        return;
    }
    ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("Image", _image);
    e.Handled = true;
    Frame.GoBack();
}

Back to the main page:

The visual element to be animated is retrieved and reverse animation is launched.


private void ItemsGridView_Loaded(object sender, RoutedEventArgs e)
{
    if (_navigatedUri != null)
    {
        //récupération de l'animation
        var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("Image");
        if (animation != null)
        {
            var item =  ViewModel.Items.Where(compare => compare.ImageUrl == _navigatedUri).First();

            //on scroll vers l'item
            ItemsGridView.ScrollIntoView(item, ScrollIntoViewAlignment.Default);
            ItemsGridView.UpdateLayout();

            var container = ItemsGridView.ContainerFromItem(item) as GridViewItem;
            if (container != null)
            {
                var root = (FrameworkElement)container.ContentTemplateRoot;
                var image = (Image)root.FindName("ImageItem");
                image.Opacity = 1;
                //on lance l'animation
                animation.TryStart(image);
            }
            else
            {
                animation.Cancel();
            }
        }

        _navigatedUri = null;
    }
}

Do I have to wait until all my clients have installed Windows 10 Anniversary to add conneconnected animations”?

No, you can now add updates to the Anniversary Update. But before using the ConnectedAnimationService class you will need to check that your client has the API.


private bool HaveConnectedAnimationService()
{
    return ApiInformation.IsTypePresent("Windows.UI.Xaml.Media.Animation.ConnectedAnimationService");
}

//Vérification que l'API est présente.
if(HaveConnectedAnimationService())
{
    var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("Image");
    ...
}

To go further

Link to the official document

BUILD video showing the connected animations

Link to the demo GitHub of MS