Aperçu des concepts de transformation graphique et d'animation dans WPF

Transformations graphiques (Transform)
Deux propriétés contrôlent les transformations :
RenderTransform : transformation de rendu, définie dans la classe UIElement
LayoutTransform : transformation de mise en page, définie dans la classe FrameworkElement
Les classes dérivées de Transform sont les suivantes, applicables à RenderTransform et LayoutTransform.
1. MatrixTransform : transformation matricielle
2. RotateTransform : transformation de rotation
3. ScaleTransform : transformation d'échelle via le système de coordonnées
4. SkewTransform : transformation de déformation, pouvant être appliquée dans les directions verticale et horizontale
5. TranslateTransform : transformation de déplacement
6. TransformGroup : groupe de transformations

I. Transformation de rendu RenderTransform
RenderTransform modifie uniquement la position visuelle de l'élément sans affecter la disposition, ce qui le rend idéal pour les animations et améliore les performances.

<Button x:Name="btnDemo" Content="Test" Width="80" Margin="80">
    <Button.RenderTransform>
        <TransformGroup>
            <RotateTransform CenterX="40" CenterY="40" Angle="45"/>
            <TranslateTransform X="150" Y="250"/>
        </TransformGroup>
    </Button.RenderTransform>
</Button>

II. Transformation de mise en page LayoutTransform
LayoutTransform affecte la disposition de l'interface, entraînant un recalcul du layout, ce qui peut impacter les performances. Elle est donc réservée aux transformations statiques et non aux animations.

<TextBlock Text="Bonjour Transformation" FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Bottom" Grid.Row="1">
    <TextBlock.LayoutTransform>
        <RotateTransform Angle="-90"/>
    </TextBlock.LayoutTransform>
</TextBlock>

III. Animation
Une animation est une modification continue d'attributs tels que la position, l'angle, la couleur ou l'opacité sur une période donnée. Ces attributs peuvent être des propriétés intrinsèques de l'objet ou des propriétés de transformation graphique. Notez que les propriétés animées sont des propriétés de dépendance.
Classification :
1) Interpolation linéaire
Concept : Animation qui modifie progressivement une propriété entre une valeur de départ et une valeur finale, nommée avec le format "TypeAnimation". Exemples : DoubleAnimation et ColorAnimation.
La valeur d'une propriété change continuellement ; pour chaque type de données, WPF propose une classe d'animation correspondante, dérivée de AnimationTimeline. Par exemple, DoubleAnimationBase est une classe abstraite dont dérivent trois types d'animations : simple, à images clés et le long d'un chemin.
Animation linéaire simple, composée de quatre éléments :
1. Durée (Duration) : intervalle entre le début et la fin de l'animation.
2. Valeur finale (To)
3. Amplitude (By)
4. Valeur initiale (From)
2) Animation à images clés
Concept : Animation où la valeur change brusquement d'une valeur à une autre. Les classes d'animation à images clés sont nommées avec le format "TypeAnimationUsingKeyFrames", comme DoubleAnimationUsingKeyFrames.
Pour les types String et les objets par référence, l'interpolation n'a pas de sens.
Une animation produit un effet visuel continu ; chaque petite modification d'attribut génère une nouvelle image appelée "image". La lecture successive d'images crée l'effet d'animation. Plus d'images par seconde donnent une animation plus fluide.
Les animations simples définissent uniquement le point de départ et d'arrivée ; les images intermédiaires sont calculées automatiquement, sans contrôle de l'opérateur.
Les animations à images clés se divisent en quatre types :
1. LinearDoubleKeyFrame : changement linéaire et uniforme.
2. DiscreteDoubleKeyFrame : changement discontinu et saccadé.
3. SplineDoubleKeyFrame : changement selon une courbe de Bézier.
4. EasingDoubleKeyFrame : changement avec effet d'atténuation.
3) Animation le long d'un chemin
Exemple : DoubleAnimationUsingPath
Cette classe nécessite un PathGeometry pour définir le chemin de déplacement, dont les données peuvent être écrites en syntaxe Path XAML. L'attribut Source de PathGeometry est également important.

IV. Storyboard (scénario)
Un Storyborad permet de grouper plusieurs animations.
Définition : La classe Storyboard offre la capacité de cibler des propriétés spécifiques sur des éléments spécifiques via les attributs TargetProperty et TargetName, servant de pont entre l'animation et la propriété à animer.
Déclencheurs d'événements : Pour exécuter un Storyboard, des déclencheurs sont nécessaires.
Il y a quatre emplacements pour définir des déclencheurs :
1) Dans les styles (collection Styles.Trigger)
2) Dans les modèles de données (collection DataTemplate.Trigger)
3) Dans les modèles de contrôle (collection ControlTemplate.Trigger)
4) Directement dans l'élément (collection FrameworkElement)
Exemple 1 : L'attribut Storyboard.TargetProperty spécifie la propriété à modifier. Si Storyboard.TargetName n'est pas défini, le Storyboard utilise l'élément parent, ici le bouton. [Type : collection FrameworkElement.Trigger]

<Button Padding="10" Height="50" Width="50" Content="Essai">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Width" To="100" Duration="0:0:5"/>
                        <DoubleAnimation Storyboard.TargetProperty="Height" To="100" Duration="0:0:5"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Button.Triggers>
</Button>

Les calculs dans cet exemple peuvent être réalisés via l'interface IValueConverter.
Exemple 2 : Les déclencheurs d'événements sont courants, mais on peut aussi utiliser les collections Trigger dans les styles ou modèles pour créer des déclencheurs de propriétés qui répondent aux changements de valeurs.

<Window.Resources>
    <Style x:Key="StyleBouton">
        <Style.Triggers>
            <Trigger Property="Button.IsPressed" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Width" To="100" Duration="0:0:5"/>
                            <DoubleAnimation Storyboard.TargetProperty="Height" To="100" Duration="0:0:5"/>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Button Padding="-10" Height="50" Width="50" Content="Essai 2" Style="{StaticResource StyleBouton}"/>

Dans l'exemple 2, Trigger.EnterAction définit l'action lorsque la propriété atteint une valeur spécifiée (ici, IsPressed devient true). Trigger.ExitAction peut être utilisé pour l'action inverse (lorsque IsPressed redevient false).
L'exemple 3 illustre une animation à images clés :

<StackPanel Orientation="Vertical" Grid.Column="1">
    <Border BorderBrush="Gray" BorderThickness="1">
        <Ellipse x:Name="cercleRouge" Height="36" Width="36" Fill="Red" HorizontalAlignment="Left">
            <Ellipse.RenderTransform>
                <TranslateTransform x:Name="transR"/>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Border>
    <Border BorderBrush="Gray" BorderThickness="1" Grid.Column="1">
        <Ellipse x:Name="cercleGris" Height="36" Width="36" Fill="Gray" HorizontalAlignment="Left">
            <Ellipse.RenderTransform>
                <TranslateTransform x:Name="transG"/>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Border>
    <Border BorderBrush="Gray" BorderThickness="1" Grid.Column="1">
        <Ellipse x:Name="cercleBleu" Height="36" Width="36" Fill="Blue" HorizontalAlignment="Left">
            <Ellipse.RenderTransform>
                <TranslateTransform x:Name="transB"/>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Border>
</StackPanel>
<Button Content="Go" Grid.Column="1" Grid.Row="1" Width="100" Height="40" FontSize="18">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard Duration="0:0:30">
                    <DoubleAnimation Duration="0:0:30" To="400" Storyboard.TargetName="transR" Storyboard.TargetProperty="X"/>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:30" Storyboard.TargetProperty="X" Storyboard.TargetName="transG">
                        <SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="400" KeySpline="1,0,0,1"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:30" Storyboard.TargetProperty="X" Storyboard.TargetName="transB">
                        <SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="400" KeySpline="0,1,1,0"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

Étiquettes: WPF XAML Animation Transform Storyboard

Publié le 3 juin à 02h37