Animation in Windows Store App

Introduction

In this article we will describe the animation features in a Windows 8 Metro Style Application. This section is an overview of animation; how to animate elements and apply easy functions to the animations to achieve various effects.
Here, we have to present the types of animations and their functions.

Here we will present an example to see the different types of the applications with the help of this example.

So, we have to use the steps given below.

Step 1 :  First of all you have to create a new Metro Style Application; let us see the description with images of how you will create it.

  • Open Visual Studio 2011
  • File -> New -> Project
  • Choose Template -> Visual C# -> Windows Metro Style -> Application
  • Rename this application

home.gif

Step 2 : In the Solution Explorer there are two files that we will primarily work with; MainPage.xaml and MainPage.xaml.cs files. In the images folder add an (any) image to the application.

solutionexporer.gif

Step 3 : The MainPage.xaml file is as in the following code.

Code :  Let us see the code, as given below:

<UserControl x:Class="Animation.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="768" d:DesignWidth="1366">

  <Grid x:Name="LayoutRoot" Background="yellow">

     <VisualStateManager.VisualStateGroups>

      <VisualStateGroup x:Name="OrientationStates">

        <VisualState x:Name="Full"/>

        <VisualState x:Name="Fill">

          <Storyboard>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="ContentRoot">

              <DiscreteObjectKeyFrame KeyTime="0">

                <DiscreteObjectKeyFrame.Value>

                  <Thickness>40,20,40,20</Thickness>

                </DiscreteObjectKeyFrame.Value>

              </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(StackPanel.Orientation)" Storyboard.TargetName="InputPanel">

              <DiscreteObjectKeyFrame KeyTime="0">

                <DiscreteObjectKeyFrame.Value>

                  <Orientation>Horizontal</Orientation>

                </DiscreteObjectKeyFrame.Value>

              </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.MaxWidth)" Storyboard.TargetName="Description">

                <DiscreteObjectKeyFrame KeyTime="0" Value="700">

                </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

          </Storyboard>

        </VisualState>

        <VisualState x:Name="Portrait">

            <Storyboard>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="ContentRoot">

                    <DiscreteObjectKeyFrame KeyTime="0">

                        <DiscreteObjectKeyFrame.Value>

                            <Thickness>40,20,40,20</Thickness>

                        </DiscreteObjectKeyFrame.Value>

                    </DiscreteObjectKeyFrame>

                </ObjectAnimationUsingKeyFrames>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.MaxWidth)" Storyboard.TargetName="Description">

                    <DiscreteObjectKeyFrame KeyTime="0" Value="700">

                    </DiscreteObjectKeyFrame>

                </ObjectAnimationUsingKeyFrames>

                    </Storyboard>

        </VisualState>

        <VisualState x:Name="Snapped">

          <Storyboard>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="ContentRoot">

              <DiscreteObjectKeyFrame KeyTime="0">

                <DiscreteObjectKeyFrame.Value>

                  <Thickness>20,20,20,20</Thickness>

                </DiscreteObjectKeyFrame.Value>

              </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(StackPanel.Orientation)" Storyboard.TargetName="InputPanel">

              <DiscreteObjectKeyFrame KeyTime="0">

                <DiscreteObjectKeyFrame.Value>

                  <Orientation>Vertical</Orientation>

                </DiscreteObjectKeyFrame.Value>

              </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.MaxWidth)" Storyboard.TargetName="Description">

                <DiscreteObjectKeyFrame KeyTime="0" Value="250">

                </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="LegalPanel">

                <DiscreteObjectKeyFrame KeyTime="0">

                    <DiscreteObjectKeyFrame.Value>

                        <Thickness>0,0,10,0</Thickness>

                    </DiscreteObjectKeyFrame.Value>

                </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            </Storyboard>

        </VisualState>

      </VisualStateGroup>

    </VisualStateManager.VisualStateGroups>

    <Grid x:Name="ContentRoot" Background="LightSeaGreen" Margin="100,20,100,20">

      <Grid.RowDefinitions>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="*"/>

        <RowDefinition Height="Auto"/>

      </Grid.RowDefinitions>


    <!-- Content -->

      <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Grid.Row="1" ZoomMode="Disabled">

        <StackPanel x:Name="ContentPanel">

          <StackPanel x:Name="InputPanel" Orientation="Horizontal" HorizontalAlignment="Left">

            <StackPanel>

              <TextBlock Text="Input" Style="{StaticResource H2Style}"/>

              <TextBlock Text="Select Input" Style="{StaticResource H3Style}"/>

              <ListBox x:Name="ScenarioList" Margin="0,0,20,0" HorizontalAlignment="Left">

                <ListBox.ItemTemplate>

                  <DataTemplate>

                    <TextBlock Text="{Binding Name}"/>

                  </DataTemplate>

                </ListBox.ItemTemplate>

                <ListBoxItem x:Name="Scenario1" Background="Aqua">

                    <TextBlock Style="{StaticResource ListBoxTextStyle}" Text="1. Animations overview" />

                </ListBoxItem>

                <ListBoxItem x:Name="Scenario2" Background="Brown">

                    <TextBlock Style="{StaticResource ListBoxTextStyle}" Text="2. Types of animations" />

                </ListBoxItem>

                <ListBoxItem x:Name="Scenario3" Background="BlanchedAlmond">

                    <TextBlock Style="{StaticResource ListBoxTextStyle}" Text="3. Easing functions" />

                </ListBoxItem>

            </ListBox>

            </StackPanel>

            <StackPanel Margin="0,31,0,0" >

              <TextBlock Text="Description:" Style="{StaticResource H3Style}"/>

              <StackPanel x:Name="Description" MaxWidth="900">

                 

                  <!-- Section 1 -->

                <StackPanel x:Name="Section1Input">

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Text="Animations change property values over a given period of time by calculating intermediate values between given initial and final values. The values can be of various types including Color, Double, Point, and so on depending on the property being animated."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0" Text="In the section , the Rectangle's Canvas.Left property increases from 0 to 300 over 3 seconds. The animation is set to loop indefinitely."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0"/>

                </StackPanel>

                 

                  <!-- Section 2 -->

                <StackPanel x:Name="Section2Input" Visibility="Collapsed">

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Text="Different types of animation work with different value types and calculate intermediate property values in different ways."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0" Text="The first square below uses a ColorAnimation and a DoubleAnimation to animate property values of type Color and Double using the default linear interpolation to create a smooth rate of change between initial and final values."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0" Text="The second square below replaces ColorAnimation and DoubleAnimation with versions that use keyframes. Keyframes indicate specific intermediate values to occur at specific times, and also indicate how to calculate values between those times. The demonstration uses three discrete keyframes followed by an easing keyframe to create a more complex animation."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0"/>

                    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">

                        <Button x:Name="Scenario2ToggleStoryboard" Content="Begin storyboards" Margin="0,0,10,0" />

                    </StackPanel>

                </StackPanel>

                 

                  <!-- Section 3 -->

                <StackPanel x:Name="Section3Input" Visibility="Collapsed">

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Text="You can apply a variety of easing functions to animations to control how intermediate values are calculated and create realistic motion effects. The demonstration below shows the effect of some easing functions, including a graph of the selected function. Change one of the options below to see the effect of a particular function and mode."/>

                  <TextBlock Style="{StaticResource DescriptionTextStyle}" TextWrapping="Wrap" Margin="0,20,0,0"/>

                  <StackPanel Orientation="Horizontal" Margin="0,10,0,0">

                        <TextBlock Style="{StaticResource DescriptionTextStyle}" Text="Easing function:" VerticalAlignment="Center" />

                        <ComboBox x:Name="Scenario3FunctionSelector">

                            <ComboBoxItem>BounceEase</ComboBoxItem>

                            <ComboBoxItem>CircleEase</ComboBoxItem>

                            <ComboBoxItem>ExponentialEase</ComboBoxItem>

                            <ComboBoxItem>PowerEase</ComboBoxItem>

                        </ComboBox>

                        <TextBlock Style="{StaticResource DescriptionTextStyle}" Text="Easing mode:" Margin="10,0,0,0" VerticalAlignment="Center" />

                        <ComboBox x:Name="Scenario3EasingModeSelector">

                            <ComboBoxItem>EaseIn</ComboBoxItem>

                            <ComboBoxItem>EaseOut</ComboBoxItem>

                            <ComboBoxItem>EaseInOut</ComboBoxItem>

                        </ComboBox>

                    </StackPanel>

                </StackPanel>                 

               </StackPanel>

            </StackPanel>

          </StackPanel>

           

            <!-- Output section -->

          <TextBlock Text="Output" Margin="0,25,0,20" Style="{StaticResource H2Style}"/>

          <StackPanel x:Name="Output"  HorizontalAlignment="Left">

             

              <!-- Section 1-->

            <Grid x:Name="Section1Output" HorizontalAlignment="Left">

                <Grid.Resources>

                    <Storyboard x:Name="Section1Storyboard">

                        <!-- This animation will animate the value of the Canvas.Left property of the rectangle Section1Rectangle to 300. -->

                        <DoubleAnimation

                            Storyboard.TargetName="Section1Rectangle"

                            Storyboard.TargetProperty="(Canvas.Left)"

                            Duration="0:0:3"

                            To="300"

                            RepeatBehavior="Forever" />

                    </Storyboard>

                </Grid.Resources>

                <Canvas Width="400" Height="100">

                    <Rectangle Name="Section1Rectangle" Width="100" Height="100" Fill="Indigo" />

                </Canvas>

            </Grid>

 

            <!-- Section 2 -->

            <Grid x:Name="Section2Output" HorizontalAlignment="Left">

                <Grid.Resources>

                    <Storyboard x:Name="Section2ContinuousStoryboard">

                    

                        <ColorAnimation

                            EnableDependentAnimation="true"

                            Storyboard.TargetName="Scenario2ContinuousRectangle"

                            Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"

                            Duration="0:0:3"

                            To="Green"  />

                        <!-- This animation will animate the value of the Canvas.Left property of the rectangle Section2ContinuousRectangle to 300. -->

                        <DoubleAnimation

                            Storyboard.TargetName="Section2ContinuousRectangle"

                            Storyboard.TargetProperty="(Canvas.Left)"

                            Duration="0:0:3"

                            To="300" />

                    </Storyboard>

                     <Storyboard x:Name="Section2KeyFrameStoryboard">

                        <!-- This animation will animate the fill color of the rectangle Scenario2KeyFrameRectangle to Green, using

            keyframes to control the interpolation method. Note that the EnableDependentAnimation flag must be set to True

            in order to run this animation, as the fill color cannot be indepedently animated.    -->

                        <ColorAnimationUsingKeyFrames

                            EnableDependentAnimation="true"

                            Storyboard.TargetName="Scenario2KeyFrameRectangle"

                            Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"

                            Duration="0:0:3" >

                            <DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="Red" />

                            <DiscreteColorKeyFrame KeyTime="0:0:1" Value="Orange" />

                            <DiscreteColorKeyFrame KeyTime="0:0:2" Value="Blue" />

                            <EasingColorKeyFrame KeyTime="0:0:3" Value="Green" />

                        </ColorAnimationUsingKeyFrames>              

                        <DoubleAnimationUsingKeyFrames

                            Storyboard.TargetName="Scenario2KeyFrameRectangle"

                            Storyboard.TargetProperty="(Canvas.Left)"

                            Duration="0:0:3" >

                            <DiscreteDoubleKeyFrame KeyTime="0:0:0.5" Value="50" />

                            <DiscreteDoubleKeyFrame KeyTime="0:0:1" Value="100" />

                            <DiscreteDoubleKeyFrame KeyTime="0:0:2" Value="200" />

                            <EasingDoubleKeyFrame KeyTime="0:0:3" Value="300" />

                        </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                </Grid.Resources>

                <StackPanel>

                    <Canvas Width="400" Height="100">

                        <Rectangle Name="Scenario2ContinuousRectangle" Width="100" Height="100" Fill="Indigo" />

                    </Canvas>

                    <Canvas Width="400" Height="100" Margin="0,20,0,0">

                        <Rectangle Name="Scenario2KeyFrameRectangle" Width="100" Height="100" Fill="Indigo" />

                    </Canvas>

                </StackPanel>

            </Grid>

 

            <!-- Section 3 -->

            <StackPanel x:Name="Section3Output" >

                <StackPanel.Resources>

                    <Storyboard x:Name="Section3Storyboard">

                        <!-- this animation will animate the value of the Canvas.Left property of the rectangle Section3MovingRectangle to 240 -->

                        <DoubleAnimation x:Name="RectanglePositionAnimation"

                            Storyboard.TargetName="Section3MovingRectangle"

                            Storyboard.TargetProperty="(Canvas.Left)"

                            Duration="0:0:3"

                            RepeatBehavior="Forever"

                            From="0"

                            To="300" />

 

                        <!-- this animation will animate the value of the Canvas.Left property of the ellipse GraphMarker to 50 -->

                        <DoubleAnimation x:Name="GraphPositionMarkerXAnimation"

                            Storyboard.TargetName="GraphMarker"

                            Storyboard.TargetProperty="(Canvas.Left)"

                            Duration="0:0:3"

                            RepeatBehavior="Forever"

                            From="0"

                            To="100" />

 

                        <!-- this animation will animate the value of the Canvas.Top property of the ellipse GraphMarker to 50 -->

                        <DoubleAnimation x:Name="GraphPositionMarkerYAnimation"

                            Storyboard.TargetName="GraphMarker"

                            Storyboard.TargetProperty="(Canvas.Top)"

                            Duration="0:0:3"

                            RepeatBehavior="Forever"

                            From="0"

                            To="100" />

                    </Storyboard>

                </StackPanel.Resources>

                <StackPanel>

                    <TextBlock Style="{StaticResource DescriptionTextStyle}" Text="Function graph:" VerticalAlignment="Center" />

                    <Canvas Name="GraphContainer" RenderTransformOrigin="0,0.5" Height="100" Width="100">

                        <Canvas.RenderTransform>

                            <ScaleTransform ScaleY="-1" />

                        </Canvas.RenderTransform>

                        <Canvas Name="Graph" />

                        <Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="1" Width="1" Height="100" />

                        <Line X1="0" Y1="0" X2="100" Y2="1" Stroke="Gray" StrokeThickness="1" Width="100" Height="1" />

                       <Ellipse Name="GraphMarker" Fill="Orange" Width="5" Height="5" />

                    </Canvas>

                </StackPanel>

                 <StackPanel Margin="10,0,0,0">

                    <TextBlock Style="{StaticResource DescriptionTextStyle}" Text="Animation result:" VerticalAlignment="Center" />

                    <Border BorderBrush="Black" BorderThickness="1">

                        <Canvas Width="400" Height="100">

                            <Rectangle Name="Section3MovingRectangle" Width="100" Height="100" Fill="Blue" />

                        </Canvas>

                    </Border>

                </StackPanel>

             </StackPanel>

            </StackPanel>

        </StackPanel>

      </ScrollViewer>

     </Grid>

  </Grid>

</UserControl>

Step 4 : After running this code we get the following output as given below.

output1.gif

output1.1.gif

output2.gif

output2.1.gif

output3.gif

output3.1.gif

Resources

Here are some useful resources.

Simple UI Animation through XAML in Metro Style Application
Binding and Defining Layout Through XAML in Metro Style Application
Introduction to Windows 8 Metro Style Application
Consuming a JSON Service in Window 8 Metro Style Application
Windows 8: Adding Shortcuts to Metro UI