• Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 29/04/2014

Créer des animations

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Des contrôles, du dessin ... nous sommes presque prêts à réaliser des jolies interfaces en laissant parler notre créativité. Mais tout cela manque un peu de dynamique, de trucs qui bougent et nous en mettent plein la vue.

Le XAML nous a entendu ! Grâce à lui, il est très facile de créer des animations. Elles vont nous servir à mettre en valeur certains éléments, ou réaliser un effet de transition en rajoutant du mouvement et de l’interactivité. Bref, de quoi innover un peu et embellir vos applications.

Nous allons découvrir dans ce chapitre comment tout cela fonctionne et comment réaliser nos propres animations directement en manipulant le XAML, ou encore grâce à l'outil professionnel de design : Expression Blend. Soyez prêt à ce que ça bouge :)

Principe généraux des animations

Une animation consiste à faire varier les propriétés d’un contrôle dans un temps précis. Par exemple, si je veux faire bouger un contrôle dans un Canvas, je vais pouvoir faire varier les propriétés Canvas.Top et Canvas.Left. De la même façon, si je veux faire disparaitre un élément avec ce que l’on appelle communément l’effet « fade », je vais pouvoir faire varier la propriété d’opacité d’un contrôle.

Pour cela, le XAML possède plusieurs classes qui vont nous être utiles. Des classes permettant de faire varier une propriété de type couleur, une propriété de type double et une propriété de type Point qui sont respectivement les classes ColorAnimation, DoubleAnimation et PointAnimation.

Pour fonctionner, elles ont besoin d’une autre classe qui s’occupe de contrôler les animations afin d’indiquer leurs cibles et la planification de l’animation. Il s’agit de la classe StoryBoard dont le nom explicite rappelle un peu les projets de montage audio ou vidéo. C’est le même principe, c’est elle qui va cadencer les différentes animations.

Création d’une animation simple (XAML)

Pour illustrer les animations, je vais vous montrer l’effet de disparition (« fade ») appliqué à un contrôle.
Créons donc un contrôle, par exemple un StackPanel contenant un bouton et un TextBlock. J’ai besoin également d’un autre bouton qui va me permettre de déclencher l’animation :

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="LeStackPanel">
        <Button Content="Cliquez-moi !" />
        <TextBlock Text="Je vais bientôt disparaître ..." />
    </StackPanel>
    <StackPanel Grid.Row="1">
        <Button Content="Démarrer l'animation" Tap="Button_Tap" />
    </StackPanel>
</Grid>

Nous allons maintenant créer notre Storyboard. Celui-ci doit se trouver en ressources. Comme on l’a déjà vu, vous pouvez le mettre en ressources de l’application, de la page ou bien en ressources d’un contrôle parent. Mettons-le dans les ressources de la grille :

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.Resources>
        <Storyboard x:Name="MonStoryBoard">
        </Storyboard>
    </Grid.Resources>

    <StackPanel x:Name="LeStackPanel">
        <Button Content="Cliquez-moi !" />
        <TextBlock Text="Je vais bientôt disparaître ..." />
    </StackPanel>
    <StackPanel Grid.Row="1">
        <Button Content="Démarrer l'animation" Tap="Button_Tap" />
    </StackPanel>
</Grid>

Ce Storyboard doit avoir un nom afin d’être manipulé par le clic sur le bouton. Il faut maintenant définir l’animation :

<Storyboard x:Name="MonStoryBoard">
    <DoubleAnimation From="1.0" To="0.0" Duration="0:0:2"
                        Storyboard.TargetName="LeStackPanel"
                        Storyboard.TargetProperty="Opacity"/>
</Storyboard>

Il s’agit d’une animation de type double où nous allons animer la propriété Opacity pour la faire aller de la valeur 1 (visible) à la valeur 0 (invisible) pendant une durée de deux secondes, ciblant notre contrôle nommé LeStackPanel.
Il faut maintenant déclencher l’animation lors du clic sur le bouton :

private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    MonStoryBoard.Begin();
}

Difficile de vous faire une copie d’écran du résultat mais n’hésitez pas à essayer par vous-même (voir la figure suivante).

L'animation de l'opacité fait disparaître le contrôle
L'animation de l'opacité fait disparaître le contrôle

Il est possible de faire en sorte que l’animation se joue en boucle et de manière indéfinie. Il suffit de rajouter les propriétés AutoReverse et RepeatBehavior. Par exemple, ici je vais animer un bouton de manière à ce qu’il se déplace de gauche à droite et de droite à gauche indéfiniment.

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.Resources>
        <Storyboard x:Name="MonStoryBoard">
            <DoubleAnimation From="0" To="200" Duration="0:0:3" 
                                AutoReverse="True" RepeatBehavior="Forever" 
                                Storyboard.TargetName="MonBouton"  Storyboard.TargetProperty="(Canvas.Left)"/>
        </Storyboard>
    </Grid.Resources>

    <Canvas Width="480" Height="500" x:Name="LeCanvas">
        <Button x:Name="MonBouton" Content="Cliquez-moi !" />
    </Canvas>
    <StackPanel Grid.Row="1">
        <Button Content="Démarrer l'animation" Tap="Button_Tap" />
    </StackPanel>
</Grid>

Nous pouvons contrôler plus finement une animation. Jusqu’à présent, nous avons utilisé la méthode Begin() pour démarrer une animation. Vous pouvez également utiliser la méthode Stop() pour arrêter une animation, la méthode Pause() pour la mettre en pause et la méthode Resume() pour la reprendre.
Vous pouvez également faire des animations de transformations. Il suffit de combiner l’utilisation des transformations et d’une DoubleAnimation. Par exemple, ici je vais faire tourner mon bouton de 90 degrés et le faire revenir à sa position initiale :

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.Resources>
        <Storyboard x:Name="MonStoryBoard">
            <DoubleAnimation From="0" To="90" Duration="0:0:1" AutoReverse="True" 
                            Storyboard.TargetName="Rotation" Storyboard.TargetProperty="Angle"/>
        </Storyboard>
    </Grid.Resources>

    <StackPanel>
        <Button x:Name="MonBouton" Content="Cliquez-moi !">
            <Button.RenderTransform>
                <RotateTransform x:Name="Rotation" Angle="0" />
            </Button.RenderTransform>
        </Button>
    </StackPanel>
    <StackPanel Grid.Row="1">
        <Button Content="Démarrer l'animation" Tap="Button_Tap" />
    </StackPanel>
</Grid>

Il suffit de cibler la propriété Angle de l’objet RotateTransform.
Si vous voulez qu’une animation démarre à partir d’un certain temps, vous pouvez rajouter la propriété BeginTime au Storyboard :

<Storyboard x:Name="MonStoryBoard" BeginTime="0:0:2">
    <DoubleAnimation From="0" To="90" Duration="0:0:1" AutoReverse="True" 
                Storyboard.TargetName="Rotation"  Storyboard.TargetProperty="Angle"/>
</Storyboard>

Par exemple ici, l’animation va durer une seconde et démarrera deux secondes après son déclenchement via la méthode Begin().
On peut contrôler plus finement une animation grâce aux animations dites « Key Frame » qui permettent d’indiquer différents moments clés d’une animation. Il est possible ainsi de spécifier la valeur de la propriété animée à un moment T. On utilisera les trois types d’animations suivantes :

  • DoubleAnimationUsingKeyFrames

  • ColorAnimationUsingKeyFrames

  • PointAnimationUsingKeyFrames

Chacune de ces animations peut être de trois types : Linear, Discret et Spline.
L’animation linéaire se rapproche des animations que nous avons vues précédemment dans la mesure où entre les moments clés, l’animation passera par toutes les valeurs séparant les deux valeurs des moments clés.
On pourrait illustrer ceci en simulant un « secouage » de bouton afin d’attirer l’attention de l’utilisateur. Le « secouage » va consister à faire une rotation de X degrés dans le sens horaire, puis revenir à la position initiale, puis faire la rotation de X degrés dans le sens anti horaire et enfin revenir à la position initiale. Il y a donc cinq moments clés dans cette animation :

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.Resources>
        <Storyboard x:Name="MonStoryBoard" >
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Rotation" Storyboard.TargetProperty="Angle" RepeatBehavior="5x">
                <LinearDoubleKeyFrame Value="0" KeyTime="00:00:00"/>
                <LinearDoubleKeyFrame Value="5" KeyTime="00:00:00.1"/>
                <LinearDoubleKeyFrame Value="0" KeyTime="00:00:00.2"/>
                <LinearDoubleKeyFrame Value="-5" KeyTime="00:00:00.3"/>
                <LinearDoubleKeyFrame Value="0" KeyTime="00:00:00.4"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Grid.Resources>

    <StackPanel>
        <Button x:Name="MonBouton" Content="Cliquez-moi !" Width="200" Height="100">
            <Button.RenderTransform>
                <RotateTransform x:Name="Rotation" Angle="0" CenterX="100" CenterY="50" />
            </Button.RenderTransform>
        </Button>
    </StackPanel>
    <StackPanel Grid.Row="1">
        <Button Content="Démarrer l'animation" Tap="Button_Tap" />
    </StackPanel>
</Grid>

Étant donné que nous animons un angle, nous utiliserons la classe DoubleAnimationUsingKeyFrames. Vu que nous voulons des transitions linéaires pour une animation de type double, nous pourrons utiliser la classe LinearDoubleKeyFrame pour indiquer nos moments clés. Ainsi, j’indique qu’au moment 0, l’angle sera de 0 degrés. Une fraction de seconde plus tard, l’angle sera de 5 degrés. Au bout de deux fractions de seconde, l’angle sera à nouveau à 0 degrés. Une fraction de seconde plus tard, l’angle sera de -5 degrés et enfin, une fraction de seconde plus tard, l’angle reviendra à sa position initiale.
À noter que cette animation sera jouée 5 fois grâce à la propriété RepeatBehavior="5x".
Il y aurait encore beaucoup de choses à dire sur ce genre d’animations, mais nous allons à présent découvrir comment réaliser des animations grâce à blend.

Création d’une animation complexe (Blend)

Expression Blend, en sa qualité de logiciel de design professionnel facilite la création d’animations. Nous allons créer une petite animation inutile pour illustrer son fonctionnement. Repartez d’une page toute neuve et ouvrez-là dans Expression Blend. Pour rappel, cliquez-droit sur le fichier XAML et choisissez Ouvrir dans expression blend.
Nous allons à présent ajouter un bouton. Sélectionnez le bouton dans la boite à outils et faites le glisser sur la surface de la page (voir la figure suivante).

Ajout d'un bouton à partir de Blend
Ajout d'un bouton à partir de Blend

Allez maintenant dans le menu Fenêtre et choisissez espace de travail puis animation afin de passer dans la vue dédiée à l’animation (voir la figure suivante).

Changement de l'espace de travail
Changement de l'espace de travail

En bas, dans l’onglet Objets et chronologie, cliquez sur le plus pour créer une nouvelle animation (voir la figure suivante).

Création d'une nouvelle animation
Création d'une nouvelle animation

Donnez un nom à votre Storyboard, comme indiqué à la figure suivante.

Nommage du storyboard
Nommage du storyboard

Il apparaît ensuite en bas à droite la ligne de temps qui va nous permettre de définir des images clés (voir la figure suivante).

La ligne de temps du storyboard
La ligne de temps du storyboard

Déplacez le trait jaune qui est sous le chiffre zéro pour le placer sous le chiffre un, en le sélectionnant par le haut de la ligne. Cela nous permet de définir une image clé à la première seconde de l’animation. Nous allons déplacer le bouton vers le bas à droite. Cela signifiera que pendant cette seconde, l’animation fera le trajet de la position 0 à la position 1 correspondant au déplacement du bouton que nous avons réalisé.

Pour voir comment rend l’animation, cliquez sur le petit bouton de lecture en haut de la ligne de temps (voir la figure suivante).

Démarrage de l'animation
Démarrage de l'animation

Je ne peux pas vous illustrer le résultat, mais vous devriez voir votre rectangle se déplacer de haut en bas à droite. Essayez ! N’hésitez pas à réduire le zoom si vous ne voyez pas tout l’écran du designer. Et voilà, un début d’animation plutôt simple à faire !

Sauvegardez votre fichier et repassez dans Visual Studio. Vous pouvez voir que le fichier XAML, après rechargement, contient désormais un code qui ressemble au suivant :

<phone:PhoneApplicationPage.Resources>
    <Storyboard x:Name="MonStoryBoard">
        <DoubleAnimation Duration="0:0:1" To="166" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="button" d:IsOptimized="True"/>
        <DoubleAnimation Duration="0:0:1" To="26" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="button" d:IsOptimized="True"/>
    </Storyboard>
</phone:PhoneApplicationPage.Resources>

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="MON APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
        <TextBlock Text="nom de la page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="137,68,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
            <Button.RenderTransform>
                <CompositeTransform/>
            </Button.RenderTransform>
        </Button>
    </Grid>
</Grid>

On peut voir qu’il nous a mis une CompositeTransform dans le bouton avec une translation sur l’axe des X et sur l’axe des Y de une seconde.
Remarquez la syntaxe particulière qu’a utilisé Blend :

<DoubleAnimation Duration="0:0:1" To="166" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="button" d:IsOptimized="True"/>

et notamment sur la propriété TargetProperty. Alors que dans mon exemple, j’avais donné un nom à la transformation pour animer une propriété de cette transformation, ici Blend a choisi d’animer une propriété relative du bouton, nommé button.
Il dit qu’il va animer la propriété TranslateX de l’objet CompositeTransform faisant partie du RenderTransform correspondant au bouton, sachant que la propriété RenderTransform fait partie de la classe de base UIElement.

Revenons à Expression Blend pour rajouter une rotation. Plaçons donc notre ligne de temps sur la deuxième seconde. Je déplace mon bouton en bas à gauche afin de réaliser une translation à laquelle je vais combiner une rotation. Aller dans la fenêtre de propriétés du bouton et aller tout en bas pour cliquer sur transformer, et choisir le deuxième onglet pour faire pivoter (voir la figure suivante).

Rotation d'un contrôle via Blend
Rotation d'un contrôle via Blend

Vous pouvez désormais choisir un angle, disons 40°. Vous pouvez vérifier que la translation se fait en même temps que la rotation en appuyant sur le bouton de lecture.
Terminons enfin notre mini boucle en déplaçant la ligne de temps sur la troisième seconde et en faisant revenir le bouton à la position première et en réglant l’angle sur 360°.
Et voilà, nous avons terminé. Enfin… presque. L’animation est prête mais rien ne permet de la déclencher. Il existe une solution pour le faire avec Expression Blend, via les comportements que l’on trouve plus souvent sous le terme anglais de Behavior. J’ai choisi de ne pas en parler dans ce cours car cela nécessiterait pas mal d'explications qui ne nous serviront pas particulièrement pour la suite.
Nous allons donc retourner dans Visual Studio pour démarrer manuellement l'animation, par exemple lors du clic sur le bouton. Rajoutons donc l’événement clic directement dans notre bouton :

<Button x:Name="button" Content="Button" Height="77" Margin="98,60,165,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Tap="Button_Tap">
    <Button.RenderTransform>
        <CompositeTransform/>
    </Button.RenderTransform>
</Button>

Avec dans le code behind :

private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    MonStoryBoard.Begin();
}

Et voilà. Notre animation est terminée !

Projections 3D

Chaque élément affichable avec le XAML peut subir une projection 3D. Cela consiste à donner à une surface 2D une perspective 3D afin de réaliser un effet visuel. Plutôt qu’un long discours, un petit exemple qui parlera de lui-même. Prenons par exemple une image, l’image de la couverture de mon livre sur le C# :

<Image Source="http://uploads.siteduzero.com/files/365001_366000/365350.jpg"/>

Qui donne la figure suivante.

Image de la couverture du livre pour apprendre le C# dans l'émulateur
Image de la couverture du livre pour apprendre le C# dans l'émulateur

Pour lui faire subir un effet de perspective, nous pouvons utiliser le XAML suivant :

<Image Source="http://uploads.siteduzero.com/files/365001_366000/365350.jpg">
    <Image.Projection>
        <PlaneProjection RotationX="-35" RotationY="-35" RotationZ="15" />
    </Image.Projection>
</Image>

qui lui fera subir une rotation de -35° autour de l’axe des X, de -35° autour de l’axe des Y et de 15° autour de l’axe des Z, ce qui donnera la figure suivante.

L'image avec une projection 3D
L'image avec une projection 3D

Plutôt sympa comme effet non ? Nous avons utilisé la classe PlaneProjection pour le réaliser.
Il existe une autre classe permettant de faire des projections suivant une matrice 3D, il s’agit de la classe Matrix3DProjection mais je pense que vous ne vous servirez que de la projection plane.

Alors, c’est très joli comme ça, mais combiné à une animation, c’est encore mieux.
Prenons le XAML suivant :

<phone:PhoneApplicationPage.Resources>
    <Storyboard x:Name="Sb">
        <DoubleAnimation Storyboard.TargetName="Projection" Storyboard.TargetProperty="RotationZ"
                            From="0" To="360" Duration="0:0:5" />
        <DoubleAnimation Storyboard.TargetName="Projection" Storyboard.TargetProperty="RotationY"
                            From="0" To="360" Duration="0:0:5" />
    </Storyboard>
</phone:PhoneApplicationPage.Resources>
<StackPanel>
    <Image Source="http://uploads.siteduzero.com/files/365001_366000/365350.jpg">
        <Image.Projection>
            <PlaneProjection x:Name="Projection" RotationX="0" RotationY="0" RotationZ="0" />
        </Image.Projection>
    </Image>
</StackPanel>

Vous vous doutez que je vais animer la rotation sur l’axe des Y et sur l’axe des Z de 0 à 360 degrés pendant une durée de 5 secondes …
Difficile de vous montrer le résultat, mais je ne peux que vous encourager à tester chez vous (voir la figure suivante).

Animation d'une projection 3D
Animation d'une projection 3D

Vous n’aurez bien sûr pas oublié de démarrer l’animation, par exemple depuis l’événement de chargement de page :

public MainPage()
{
    InitializeComponent();
    Loaded += MainPage_Loaded;
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    Sb.Begin();
}
  • Le XAML possède un framework complexe d’animation.

  • Blend se révèle un atout de qualité dans la réalisation d’animations complexes.

  • Les projections 3D permettent d’ajouter un effet de perspective 3D dont le rendu est plutôt intéressant.

Voilà pour cette introduction à XAML ou à Silverlight pour Windows Phone. Je n’ai bien sûr pas pu tout présenter et je m’excuse d’être passé rapidement sur certains points afin que ce cours garde une taille raisonnable et éviter de vous endormir avec plein de petits détails. N’hésitez pas à creuser les points qui vous intéressent, la documentation MSDN est plutôt bien fournie sur le sujet.

Vous avez cependant toutes les bases vous permettant de démarrer la réalisation d’applications pour vos Windows Phone. Alors, n’hésitez pas à vous entraîner sur ce que vous avez appris et ensuite à découvrir la suite du cours où nous allons plonger petit à petit dans les spécificités de Windows Phone …

Exemple de certificat de réussite
Exemple de certificat de réussite