Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Multiple Animations in WPF

0.00/5 (No votes)
30 Mar 2015 1  
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.

 <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:

<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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here