Click here to Skip to main content
15,881,248 members
Articles / Desktop Programming / WPF
Tip/Trick

Multiple Animations in WPF

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
30 Mar 2015CPOL3 min read 21.4K   498   9   3
Running multiple animations in one WPF XAML

Introduction

The purpose of this tip is to demonstrate using multiple animations in a WPF XAML.

Background

The idea behind this animation came from this post. So after a few tries and mistakes, the resulting loading screen was created.

Using the Code

All code is in LoadingCircle.xaml.

From the original .gif, we were able to find that there are 24 dots rotating around the circle. Meaning that each dot is 15o from each other, 360o / 24 = 15o, which was translated to radians, xo * PI / 180o. Knowing the location of each dot starting location, we had to translate to a canvas' left and top location. Knowing we want a dot to be an ellipse with width and height of unit size 2 on a circle with a diameter of 22 units, we can calculate the left of the canvas to be centerx + (radius * cos (radian value)) and the top of the canvas to be centery + (radius * sin (radian value)) for each dot location.

It is noted from the original .gif that each dot rotates with the 3rd dot down. That is dot 1 rotates with dot 4, dot 3 with dot 6, etc., and ending with dot 23 with dot 2. Knowing this, we see that we need to use multiple canvas' on the main canvas. To find the center point at which the two dots rotate, we use the following formula for the Left dot1x + (dot4x + 1 - dot1x + 1) / 2, note the '+1's are due to the ellipse size, and top dot1y + (dot4y + 1 - dot1y + 1) / 2 this is the location of the canvas for the two points. We take the desired location of the dot minus the canvas location to get the location of the dot in relation to the sub-canvas. Please see the Calculations.xlsx spreadsheet for reference.

Now that we have the locations of the dots, I cheated to get the colors of the dots. I took a screen shot of the .gif and put it in paint and used color picker to get the RGB values.

With the dots located and colored, we start on the animation. You will notice that the animation is linked through the names of Controls, so always name your controls so if you need to add something, it is easier to link them.

So if we look at the main canvas and the first sub-canvas containing dots 1 & 4, we see that the whole canvas uses Storyboard SpinnerRotate to control the animation with dots 1 & 4 using Point1 and Point4, respectively, to control color changes, Group1 to control rotation, and the circle, connecting dots 1 & 4, using Group1Circle to fade in and out.

XML
<Canvas RenderTransformOrigin="0.5,0.5"
HorizontalAlignment="Center" VerticalAlignment="Center"
        Width="24" Height="24" >

           <!--Point1 and Point4-->
           <Canvas Canvas.Left="15.8890873" Canvas.Top="2.610912703"
                   RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center"
                   VerticalAlignment="Center">
               <!--Group1 Circle-->
               <Ellipse Width="8.419035512" Height="8.419035512" x:Name="Group1Circle"
                        Canvas.Left="-4.209517756" Canvas.Top="-4.209517756"
                        StrokeThickness="0.125">
                   <Ellipse.Stroke>
                       <SolidColorBrush>
                           <SolidColorBrush.Color>
                               <Color A="255" R="253" G="95" B="1" />
                           </SolidColorBrush.Color>
                       </SolidColorBrush>
                   </Ellipse.Stroke>
               </Ellipse>

               <!--Point1-->
               <Ellipse Width="2" Height="2"
               x:Name="Point1" Canvas.Left="-4.889087297"
                        Canvas.Top="-2.610912703"
                        Stretch="Fill" Fill="Red" Opacity="1.0"/>

               <!--Point4-->
               <Ellipse Width="2" Height="2"
               x:Name="Point4" Canvas.Left="2.889087297"
                        Canvas.Top="0.610912703" Opacity="1.0" >
                   <Ellipse.Fill>
                       <SolidColorBrush>
                           <SolidColorBrush.Color>
                               <Color A="255" R="251" G="190" B="3" />
                           </SolidColorBrush.Color>
                       </SolidColorBrush>
                   </Ellipse.Fill>
               </Ellipse>

               <Canvas.RenderTransform>
                   <RotateTransform x:Name="Group1" Angle="135" />
               </Canvas.RenderTransform>
           </Canvas>

           <Canvas.Triggers>
               <EventTrigger RoutedEvent="ContentControl.Loaded">
                   <BeginStoryboard Storyboard="{StaticResource SpinnerRotate}" />
               </EventTrigger>
           </Canvas.Triggers>
       </Canvas>

These connect to animations:

XML
<Storyboard x:Key="SpinnerRotate" RepeatBehavior="Forever">
            <!--Init-->
            <DoubleAnimation  BeginTime="00:00:00.00" Storyboard.TargetName="Group1Circle"  
                              Storyboard.TargetProperty="Opacity" From="0" To="0" 
                              Duration="0:0:00.00" />

            <!--First Time Around-->
            <DoubleAnimation  BeginTime="00:00:00.00" Storyboard.TargetName="Group1"  
                              Storyboard.TargetProperty="(RotateTransform.Angle)" From="135" 
                              To="180" Duration="0:0:00.25" />

            <!--Second Time Around-->
            <DoubleAnimation  BeginTime="00:00:02.50" Storyboard.TargetName="Group1"   
                              Storyboard.TargetProperty="(RotateTransform.Angle)" From="180" 
                              To="360" Duration="0:0:01.00" />

            <DoubleAnimation  BeginTime="00:00:02.6666" Storyboard.TargetName="Group1Circle"  
                              Storyboard.TargetProperty="Opacity" From="0" To="0.88" 
                              Duration="0:0:00.333" AutoReverse="True" />


            <!--Tie Loop Around-->
            <DoubleAnimation  BeginTime="00:00:05.50" Storyboard.TargetName="Group1" 
                              Storyboard.TargetProperty="(RotateTransform.Angle)" From="0" 
                              To="135" Duration="0:0:00.75" />
            
            <DoubleAnimation  BeginTime="00:00:05.6665" Storyboard.TargetName="Group1Circle" 
                              Storyboard.TargetProperty="Opacity" From="0" To="0.88" 
                              Duration="0:0:00.333" AutoReverse="True" />

            <!--Point1 to Point4-->
            <ColorAnimation BeginTime="00:00:00.00" Storyboard.TargetName="Point1" 
                            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
                            From="Red" Duration="0:0:00.25">
                <ColorAnimation.To>
                    <Color A="255" R="251" G="190" B="3" />
                </ColorAnimation.To>
            </ColorAnimation>
            <ColorAnimation BeginTime="00:00:02.50" Storyboard.TargetName="Point1" 
                            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
                            To="Red" Duration="0:0:01">
                <ColorAnimation.From>
                    <Color A="255" R="251" G="190" B="3" />
                </ColorAnimation.From>
            </ColorAnimation>
            <ColorAnimation BeginTime="00:00:00.00" Storyboard.TargetName="Point4" 
                            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
                            To="Red" Duration="0:0:00.25">
                <ColorAnimation.From>
                    <Color A="255" R="251" G="190" B="3" />
                </ColorAnimation.From>
            </ColorAnimation>
            <ColorAnimation BeginTime="00:00:02.50" Storyboard.TargetName="Point4" 
                            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
                            From="Red" Duration="0:0:01">
                <ColorAnimation.To>
                    <Color A="255" R="251" G="190" B="3" />
                </ColorAnimation.To>
            </ColorAnimation>

</Storyboard>

So one can see that each animation is linked by their name and each name can have multiple animations. In this case, different animations at different times.

Points of Interest

It is to be noted that the first couple of dots are started through most of their rotations to give a seamless transition from the last animation to the first.

If you want to make this a splash screen, here is a great article that shows how to override the Startup function in App.xaml.cs.

History

  • Created: 3/30/2015

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCould you provide a project with this code? Pin
tal_segal31-Mar-15 20:10
tal_segal31-Mar-15 20:10 
AnswerRe: Could you provide a project with this code? Pin
lally72710-Apr-15 9:20
lally72710-Apr-15 9:20 
GeneralRe: Could you provide a project with this code? Pin
tal_segal10-Apr-15 11:00
tal_segal10-Apr-15 11:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.