Voici venu le temps des Storyboards et des propdp !

« Bonjour à tous les amis ! »

« Aujourd’hui on va s’amuser avec les Storyboards ! »
« Quoi tu ne sais pas ce que c’est un storyboard ? »

Casimir_20061112_Paris_Jouets_Collections

« Quitte immédiatement l’île aux enfants, espèce d’ignorant, et ne revient pas avant d’avoir révisé sur MSDN ! »

Storyboardez-moi ou je fais un malheur !

Quand Casimir fait du XAML, ce qu’il aime par dessus tout c’est créer des animations avec les Storyboards.
Mais bien vite il s’aperçoit que malgré la puissance diabolique de Blend il est parfois compliqué de dynamiser ses animations.
Difficile par exemple d’animer une ellipse en suivant un chemin circulaire dont le rayon varie selon la valeur d‘un contrôle Slider.
Alors il erre comme une âme en peine autour de l’île puis s’en va vers le kiosque de Julie.

Comme la biaâatch* n’est pas là, il en profite pour regarder un vieux « Programmez » et tombe sur un article fort intéressant de David Catuhe sur les Properties Dependency

*NDLR : C’est évidemment pour rire car Casimir n’a aucun notion de ce qu’est le GangstaRap.

« Bon sang mais c’est bien sûr ! » s’écrit alors Casimir !

CPF86634677

Ma dépendence à certaines Propriétés*

*NDLR: Le Gloubi-boulga, est un puissant stupéfiant de catégorie 4.

Les properties Dependency sont Bindables, Styleables et, c’est ce qui nous intéresse ici, sont aussi utilisables par des storyboards comme « TargetProperty ».

Grâce au snippet « propdp » Casimir crée une property dependency « Angle » (il tape propdp puis la touche tab et il complète).
Cela génére plein de « blabla » mais il ne faut pas avoir peur, petit enfant, car il suffit juste de modifier le type de la propriété (« double ») puis son nom (« Angle »), la classe qui la contient (à savoir ma page XAML et donc « MainPage ») et enfin sa propriété par défaut (« 0.0 »).

        /// <summary>
        /// Angle en degré
        /// </summary>

        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }
        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.Register("Angle", typeof(double), typeof(MainPage), new PropertyMetadata(0.0));

Avant de créer son Storyboard Casimir va rajouter un nom à la page coté XAML afin qu’il puisse trouver la propdp Angle que l’on vient d’ajouter.
Ce nom « MyPage » sera le « TargetName » de notre futur Storyboard.

<phone:PhoneApplicationPage    
    x:Name="MyPage"
    ...
>
...
</phone:PhoneApplicationPage>

Casimir peut maintenant créer notre Storyboard dans les ressources de la MainPage.
C’est une animation de double de la propriété Angle de notre page « MyPage ».
Elle dure 5 secondes et va de la valeur 0 à 360.
Elle représentera les angles en degré de notre cercle.

    <phone:PhoneApplicationPage.Resources>
        <Storyboard RepeatBehavior="Forever" x:Name="StoryboardCircle">
            <DoubleAnimation Duration="00:00:05" From="0" To="360" Storyboard.TargetProperty="Angle" Storyboard.TargetName="MyPage">
                <DoubleAnimation.EasingFunction>
                    <ElasticEase EasingMode="EaseOut"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>        
    </phone:PhoneApplicationPage.Resources>

Comme tu le sais Casimir aime rire et rajoute donc une fonction Easing de type « Elastic » à son animation qui lui permet de simuler un mouvement, euuuuuh, d’élastique.

Il ne reste plus qu’à détecter les changements de la propriétés Angle. Pour cela Casimir crée un méthode static du plus bel effet.

        private static void OnDrawChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            MainPage page = (MainPage)sender;
	    // toi, on se revoit tout à l'heure
            page.Transform();
        }

et la relie à sa property dependency « Angle » dans la déclaration de l’objet PropertyMetadata :

        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.Register("Angle", typeof(double), typeof(MainPage), new PropertyMetadata(0.0, OnDrawChanged));

La transformation s’effectuera dans une méthode Transform qui sera chargée d’effectuer une translation des X et Y de ellipse à animer selon l’angle reçu.
Comme l’ellipse est auto-centrée par le biais de son container Grid, Casimir a juste à s’occuper du petit algo de transformation en cercle.
Un cos pour X et un sin pour Y, le tout multiplié par le rayon, font parfaitement l’affaire.

    private void Transform()
    {
        var radian = DegreeToRadian(this.Angle);
                
        this.EllipseTransform.TranslateX = this.Ray * Math.Cos(radian);
        this.EllipseTransform.TranslateY = this.Ray * Math.Sin(radian);
    }
    <Ellipse Width="100" Height="100" Fill="Red">
        <Ellipse.RenderTransform>
            <CompositeTransform x:Name="EllipseTransform"></CompositeTransform>
        </Ellipse.RenderTransform>
    </Ellipse>

« Ray » est également une property dependency qui représente le rayon du cercle.
Elle permet à Casimir de se binder élégamment à un slider coté XAML :

     <Slider Minimum="0" Maximum="200" Value="{Binding Path=Ray, ElementName=MyPage, Mode=TwoWay}"  Margin="0,0,0,-24" />

La propdp « Ray » appellera ensuite la méthode « Transform » de la même manière que la propdp « Angle ».

« Ça, mon vieux Casimir, c’est pas du code de morveux ! » se dit Casimir.

Conclusion

– « Storyboard et Property Dependecy peuvent donner dans certain cas d’animation complexe un combo extrêmement puissant qui apportera puissance et souplesse à son maître »
– « Un peu comme quand je tente une Fusion avec Hyppolyte ? » demanda Casimir.

ile-enfants-casimir-hypolite-big

– « Non Casimir »

Vous trouverez le code complet de cet article en suivant ce lien !

leave your comment