SDK Anniversary : les connected animations

SDK Anniversary : les connected animations

Il a toujours été fastidieux dans les apps XAML de faire des animations de transition entre deux pages.
Pour animer une image entre deux pages, il fallait modifier le système de navigation pour permettre ces animations.
L’anniversary update apporte un nouveau moyen appelé les “connected animations” qui rend ces animations triviale à réaliser.

connectedanimation

Comment ça fonctionne ?

La classe ConnectedAnimationService permet de passer un élément visuel entre plusieurs page XAML.
Nous allons coder ensemble un exemple pour comprendre comment cela fonctionne.

Page maître:

<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);
}

Page de détail :

Le 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>

Le code C#

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;
}

Lorsque l’utilisateur click sur back on prépare l’animation pour que la page maître puisse jouer l’animation.

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

Au retour sur la page maître:

On récupère l’élément visuel à animer et lance l’animation inverse.

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;
    }
}

Dois-je attendre que tous mes clients aient installé Windows 10 Anniversary pour ajouter des “connected animations”?

Non, vous pouvez dès à présent ajouter des nouveautés d’anniversary Update. Mais avant d’utiliser la classe ConnectedAnimationService il faudra vérifier si votre client à bien l’API présente. Ci dessous le code vérification :

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");
    ...
}

Pour aller plus loin

Lien vers la doc officielle
Vidéo de BUILD montrant les connected animations
Lien vers le GitHub de démo de MS

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Pin It on Pinterest