Partager via


Animations d’images clés et animations de fonction d’accélération

Les animations d’images clés linéaires, les animations de trame clé avec une valeur KeySpline ou les fonctions d’accélération sont trois techniques différentes pour environ le même scénario : création d’une animation storyboard un peu plus complexe et qui utilise un comportement d’animation non linéaire d’un état de départ à un état final.

Prérequis

Vérifiez que vous avez lu la rubrique d’animations storyboarded. Cette rubrique s’appuie sur les concepts d’animation qui ont été expliqués dans les animations storyboarded et ne les reprendra pas. Par exemple, les animations storyboarded décrivent comment cibler des animations, des storyboards en tant que ressources, les valeurs de propriété Timeline telles que Duration, FillBehavior, etc.

Animation à l’aide d’animations d’images clés

Les animations de trame clé permettent d’atteindre plusieurs valeurs cibles atteintes à un point le long de la chronologie d’animation. En d’autres termes, chaque image clé peut spécifier une valeur intermédiaire différente, et la dernière image clé atteinte est la valeur d’animation finale. En spécifiant plusieurs valeurs à animer, vous pouvez créer des animations plus complexes. Les animations de trame clé permettent également une logique d’interpolation différente, chacune implémentée en tant que sous-classe KeyFrame différente par type d’animation. Plus précisément, chaque type d’animation d’images clés a une variante Discrète, Linéaire, Spline et Accélération de sa classe KeyFrame pour spécifier ses images clés. Par exemple, pour spécifier une animation qui cible un double et utilise des images clés, vous pouvez déclarer des images clés avec DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame et EasingDoubleKeyFrame. Vous pouvez utiliser n’importe quel type et tous ces types au sein d’une collection KeyFrames unique pour modifier l’interpolation chaque fois qu’une nouvelle image clé est atteinte.

Pour le comportement d’interpolation, chaque image clé contrôle l’interpolation jusqu’à ce que son heure KeyTime soit atteinte. Sa valeur est également atteinte à ce moment-là. S’il y a plus d’images clés au-delà, la valeur devient la valeur de départ de l’image clé suivante dans une séquence.

Au début de l’animation, si aucune image clé avec KeyTime de « 0:0:0 » existe, la valeur de départ est quelle que soit la valeur non animée de la propriété. Cela est similaire à la façon dont une animation From/to/By agit s’il n’y a pas De.

La durée d’une animation de trame clé est implicitement la durée égale à la valeur KeyTime la plus élevée définie dans l’une de ses images clés. Vous pouvez définir une durée explicite si vous le souhaitez, mais soyez prudent, mais il n’est pas plus court qu’un KeyTime dans vos propres images clés ou vous couperez une partie de l’animation.

En plus de la durée, vous pouvez définir toutes les propriétés de chronologie basées sur une animation de trame clé, comme vous pouvez avec une animation From/To/By, car les classes d’animation de trame clé dérivent également de Timeline. Il s’agit des étapes suivantes :

  • Correction automatique : une fois que le dernier frame clé est atteint, les images sont répétées dans l’ordre inverse de la fin. Cela double la durée apparente de l’animation.
  • BeginTime : retarde le début de l’animation. La chronologie des valeurs KeyTime dans les images ne commence pas à compter tant que BeginTime n’est pas atteinte, il n’y a donc aucun risque de couper les images.
  • FillBehavior : contrôle ce qui se passe lorsque la dernière image clé est atteinte. FillBehavior n’a aucun effet sur les images clés intermédiaires.
  • RepeatBehavior :
    • Si la valeur est Forever, les images clés et leur chronologie se répètent infiniment.
    • Si la valeur est définie sur un nombre d’itérations, la chronologie se répète plusieurs fois.
    • Si elle est définie sur une durée, la chronologie se répète jusqu’à ce que cette heure soit atteinte. Cela peut tronquer la partie d’animation dans la séquence d’images clés, s’il ne s’agit pas d’un facteur entier de la durée implicite de la chronologie.
  • SpeedRatio (non couramment utilisé)

Images clés linéaires

Les images clés linéaires entraînent une interpolation linéaire simple de la valeur jusqu’à ce que le KeyTime de l’image soit atteint. Ce comportement d’interpolation est le plus similaire aux animations Plus simples de From/To/By décrites dans la rubrique animations storyboarded.

Voici comment utiliser une animation de trame clé pour mettre à l’échelle la hauteur de rendu d’un rectangle à l’aide d’images clés linéaires. Cet exemple exécute une animation où la hauteur du rectangle augmente légèrement et linéairement pendant les 4 premières secondes, puis effectue une mise à l’échelle rapide pour la dernière seconde jusqu’à ce que le rectangle soit double de la hauteur de départ.

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="myRectangle"
              Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
                <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </StackPanel.Resources>
</StackPanel>

Images clés discrètes

Les images clés discrètes n’utilisent pas d’interpolation du tout. Lorsqu’un KeyTime est atteint, la nouvelle valeur est simplement appliquée. Selon la propriété de l’interface utilisateur animée, cela produit souvent une animation qui semble « sauter ». Soyez certain que c’est le comportement esthétique que vous voulez vraiment. Vous pouvez réduire les sauts apparents en augmentant le nombre d’images clés que vous déclarez, mais si une animation fluide est votre objectif, vous pouvez être mieux à l’aide d’images clés linéaires ou spline à la place.

Remarque

Les images clés discrètes sont la seule façon d’animer une valeur qui n’est pas de type Double, Point et Color, avec un DiscreteObjectKeyFrame. Nous aborderons cela plus en détail plus loin dans cette rubrique.

Trames clés spline

Un frame de clé spline crée une transition de variable entre les valeurs en fonction de la valeur de la propriété KeySpline . Cette propriété spécifie les premiers et deuxième points de contrôle d’une courbe de Bezier, qui décrit l’accélération de l’animation. En fait, une cléspline définit une relation fonction-over-time où le graphique de fonction est la forme de cette courbe bezier. Vous spécifiez généralement une valeur KeySpline dans une chaîne d’attribut abrégée XAML qui a quatre valeurs doubles séparées par des espaces ou des virgules. Ces valeurs sont des paires « X, Y » pour deux points de contrôle de la courbe de Bezier. « X » est l’heure et « Y » est le modificateur de fonction de la valeur. Chaque valeur doit toujours être comprise entre 0 et 1 inclus. Sans modification de point de contrôle vers un KeySpline, la ligne droite comprise entre 0,0 et 1,1 est la représentation d’une fonction au fil du temps pour une interpolation linéaire. Vos points de contrôle modifient la forme de cette courbe et donc le comportement de la fonction au fil du temps pour l’animation spline. Il est probablement préférable de voir cela visuellement comme un graphique. Vous pouvez exécuter l’exemple de visualiseur key-spline Silverlight dans un navigateur pour voir comment les points de contrôle modifient la courbe et comment un exemple d’animation s’exécute lors de son utilisation en tant que valeur KeySpline.

Cet exemple montre trois images clés différentes appliquées à une animation, la dernière étant une animation spline clé pour une valeur double (SplineDoubleKeyFrame). Notez la chaîne « 0.6,0.0 0.9,0.00 » appliquée pour KeySpline. Cela produit une courbe où l’animation semble s’exécuter lentement au début, mais atteint rapidement la valeur juste avant l’atteinte de KeyTime .

<Storyboard x:Name="myStoryboard">
    <!-- Animate the TranslateTransform's X property
        from 0 to 350, then 50,
        then 200 over 10 seconds. -->
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetName="MyAnimatedTranslateTransform"
        Storyboard.TargetProperty="X"
        Duration="0:0:10" EnableDependentAnimation="True">

        <!-- Using a LinearDoubleKeyFrame, the rectangle moves 
            steadily from its starting position to 500 over 
            the first 3 seconds.  -->
        <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>

        <!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly 
            appears at 400 after the fourth second of the animation. -->
        <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>

        <!-- Using a SplineDoubleKeyFrame, the rectangle moves 
            back to its starting point. The
            animation starts out slowly at first and then speeds up. 
            This KeyFrame ends after the 6th second. -->
        <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Accélération des images clés

Une trame clé d’accélération est une trame clé où l’interpolation est appliquée, et la fonction au fil du temps de l’interpolation est contrôlée par plusieurs formules mathématiques prédéfinies. Vous pouvez réellement produire le même résultat avec une trame clé spline que vous pouvez avec certains des types de fonctions d’accélération, mais il existe également certaines fonctions d’accélération, telles que BackEase, que vous ne pouvez pas reproduire avec un spline.

Pour appliquer une fonction d’accélération à une image clé d’accélération, vous définissez la propriété EasingFunction en tant qu’élément de propriété en XAML pour cette trame clé. Pour la valeur, spécifiez un élément d’objet pour l’un des types de fonctions d’accélération.

Cet exemple applique une cubeEase, puis une valeur BounceEase en tant que trames clés successives à un DoubleAnimation pour créer un effet de rebond.

<Storyboard x:Name="myStoryboard">
    <DoubleAnimationUsingKeyFrames Duration="0:0:10"
        Storyboard.TargetProperty="Height"
        Storyboard.TargetName="myEllipse">

        <!-- This keyframe animates the ellipse up to the crest 
            where it slows down and stops. -->
        <EasingDoubleKeyFrame Value="-300" KeyTime="00:00:02">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>

        <!-- This keyframe animates the ellipse back down and makes
            it bounce. -->
        <EasingDoubleKeyFrame Value="0" KeyTime="00:00:06">
            <EasingDoubleKeyFrame.EasingFunction>
                <BounceEase Bounces="5"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Il s’agit simplement d’un exemple de fonction d’accélération. Nous aborderons plus en détail la section suivante.

Fonction d'accélération

Les fonctions d’accélération permettent d’appliquer des formules mathématiques personnalisées à des animations. Les opérations mathématiques sont souvent utiles pour produire des animations qui simulent la physique réelle dans un système de coordonnées 2D. Par exemple, vous pouvez faire en sorte qu’un objet rebondisse ou se comporte comme s’il était sur un ressort de façon réaliste. Vous pouvez utiliser des images clés ou même des animations From/To/By pour estimer ces effets, mais il faudrait une quantité importante de travail et l’animation serait moins précise que l’utilisation d’une formule mathématique.

Les fonctions d’accélération peuvent être appliquées aux animations de trois façons :

Voici une liste des fonctions d’accélération :

  • BackEase : rétracte légèrement le mouvement d’une animation avant qu’elle ne commence à s’animer dans le chemin indiqué.
  • BounceEase : crée un effet de rebond.
  • CircleEase : crée une animation qui accélère ou décélére à l’aide d’une fonction circulaire.
  • CubeEase : crée une animation qui accélère ou décélérée à l’aide de la formule f(t) = t3.
  • ElasticEase : crée une animation qui ressemble à un ressort oscillant de retour et d’avant jusqu’à ce qu’il arrive au repos.
  • ExponentielleEase : crée une animation qui accélère ou décélére à l’aide d’une formule exponentielle.
  • PowerEase : crée une animation qui accélère ou décélérée à l’aide de la formule f(t) = tp où p est égal à la propriété Power .
  • QuadraticEase : crée une animation qui accélère ou décélérée à l’aide de la formule f(t) = t2.
  • QuarticEase : crée une animation qui accélère ou décélérée à l’aide de la formule f(t) = t4.
  • QuinticEase : créez une animation qui accélère ou décélére à l’aide de la formule f(t) = t5.
  • SineEase : crée une animation qui accélère ou décélérée à l’aide d’une formule sinusoïque.

Certaines des fonctions d’accélération ont leurs propres propriétés. Par exemple, BounceEase a deux propriétés Bounces et Bounciness qui modifient le comportement de fonction au fil du temps de ce BounceEase particulier. D’autres fonctions d’accélération telles que CubicEase n’ont pas de propriétés autres que la propriété EasingMode que toutes les fonctions d’accélération partagent et produisent toujours le même comportement de fonction au fil du temps.

Certaines de ces fonctions d’accélération ont un peu de chevauchement, selon la façon dont vous définissez les propriétés sur les fonctions d’accélération qui ont des propriétés. Par exemple, QuadraticEase est exactement la même qu’une PowerEase avec Power égale à 2. Et CircleEase est essentiellement une valeur exponentielle par défaut.

La fonction d’accélération BackEase est unique, car elle peut modifier la valeur en dehors de la plage normale telle qu’elle est définie par From/To ou les valeurs des images clés. Elle démarre l’animation en modifiant la valeur dans la direction opposée, comme prévu à partir d’un comportement Normal De/À, revient à la valeur From ou de départ, puis exécute l’animation comme normale.

Dans un exemple précédent, nous avons montré comment déclarer une fonction d’accélération pour une animation clé-image. Cet exemple suivant applique une fonction d’accélération à une animation From/To/By.

<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                Storyboard.TargetName="myRectangle" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <DoubleAnimation.EasingFunction>
                    <BounceEase Bounces="2" EasingMode="EaseOut" 
                                Bounciness="2"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </StackPanel.Resources>
    <Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>

Lorsqu’une fonction d’accélération est appliquée à une animation From To/By, elle modifie les caractéristiques temporelles de la façon dont la valeur interpole entre les valeurs From/ et To sur la durée de l’animation. Sans fonction d’accélération, il s’agirait d’une interpolation linéaire.

Animations de valeur d’objet discrètes

Un type d’animation mérite une mention spéciale, car c’est la seule façon dont vous pouvez appliquer une valeur animée aux propriétés qui ne sont pas de type Double, Point ou Color. Il s’agit de l’animation d’image clé ObjectAnimationUsingKeyFrames. L’animation à l’aide de valeurs d’objet est différente, car il n’existe aucune possibilité d’interpoler les valeurs entre les images. Lorsque la touche KeyTime de l’image est atteinte, la valeur animée est immédiatement définie sur la valeur spécifiée dans la valeur de l’image clé. Comme il n’existe aucune interpolation, il n’existe qu’une seule image clé que vous utilisez dans la collection d’images clés ObjectAnimationUsingKeyFrames : DiscreteObjectKeyFrame.

La valeur d’un objet DiscreteObjectKeyFrame est souvent définie à l’aide de la syntaxe de l’élément de propriété, car la valeur de l’objet que vous essayez de définir n’est souvent pas expressible sous forme de chaîne pour remplir la syntaxe d’attribut. Vous pouvez toujours utiliser la syntaxe d’attribut si vous utilisez une référence telle que StaticResource.

Un emplacement où vous verrez un ObjectAnimationUsingKeyFrames utilisé dans les modèles par défaut est lorsqu’une propriété de modèle fait référence à une ressource Brush. Ces ressources sont des objets SolidColorBrush, pas seulement une valeur Color et utilisent des ressources définies comme thèmes système (ThemeDictionaries). Elles peuvent être affectées directement à une valeur de type Brush, telle que TextBlock.Foreground , et n’ont pas besoin d’utiliser le ciblage indirect. Toutefois, étant donné qu’un SolidColorBrush n’est pas double, point ou couleur, vous devez utiliser un ObjectAnimationUsingKeyFrames pour utiliser la ressource.

<Style x:Key="TextButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <TextBlock x:Name="Text"
                        Text="{TemplateBinding Content}"/>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
...
                       </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Vous pouvez également utiliser ObjectAnimationUsingKeyFrames pour animer des propriétés qui utilisent une valeur d’énumération. Voici un autre exemple d’un style nommé qui provient des modèles par défaut Windows Runtime. Notez comment elle définit la propriété Visibility qui prend une constante d’énumération Visibility. Dans ce cas, vous pouvez définir la valeur à l’aide de la syntaxe d’attribut. Vous avez uniquement besoin du nom de constante non qualifié d’une énumération pour définir une propriété avec une valeur d’énumération, par exemple « Collapsed ».

<Style x:Key="BackButtonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal"/>
...           <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
...
          </VisualStateManager.VisualStateGroups>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Vous pouvez utiliser plusieurs objet DiscreteObjectKeyFrame pour un jeu d’images ObjectAnimationUsingKeyFrames. Il peut s’agir d’un moyen intéressant de créer une animation « diaporama » en animant la valeur d’Image.Source, comme exemple de scénario pour lequel plusieurs valeurs d’objet peuvent être utiles.