In my post yesterday, I looked at doing non-linear interpolations (aka the bouncing ball effect) for animations using animation composition.  There is another way to achieve this effect using spline animations.  By using spline animations, you can specify exactly how the animation accelerates and decelerates based on a Bezier curve.  You specify this using the KeySpline property, providing the control points. 

Here is yesterday's sample using splines instead of animation composition:

<!-- Demonstrates the usage of multiple animations to simulate a ball bouncing. -->
<Page xmlns="
http://schemas.microsoft.com/winfx/avalon/2005"
    xmlns:x="
http://schemas.microsoft.com/winfx/xaml/2005"
    >
 <Page.Resources>
  <RadialGradientBrush x:Key="redBallBrush" GradientOrigin="0.75,0.25">
   <RadialGradientBrush.GradientStops>
    <GradientStop Color="Orange" Offset="0" />
    <GradientStop Color="Red" Offset="1" />
   </RadialGradientBrush.GradientStops>
  </RadialGradientBrush>

  <RadialGradientBrush x:Key="orangeBallBrush" GradientOrigin="0.75,0.25">
   <RadialGradientBrush.GradientStops>
    <GradientStop Color="Yellow" Offset="0" />
    <GradientStop Color="Orange" Offset="1" />
   </RadialGradientBrush.GradientStops>
  </RadialGradientBrush>

  <RadialGradientBrush x:Key="blueBallBrush"
   GradientOrigin="0.75,0.25">
   <RadialGradientBrush.GradientStops>
    <GradientStop Color="LightBlue" Offset="0" />
    <GradientStop Color="MediumBlue" Offset="1" />
   </RadialGradientBrush.GradientStops>
  </RadialGradientBrush>


  <Style TargetType="{x:Type TextBlock}">
   <Setter Property="FontFamily" Value="Verdana"/>
  </Style>

 </Page.Resources>

 <Page.Storyboards>

  <ParallelTimeline>

   <!-- Animates the vertical position of the first ball. A single
              animation is used. -->
   <SetterTimeline TargetName="singleAnimationBall" Path="(Canvas.Top)">
    <DoubleAnimationUsingKeyFrames Duration="0:0:3" AutoReverse="True" RepeatBehavior="Forever"
       DecelerationRatio="1" >
     <SplineDoubleKeyFrame Value="0" KeySpline="0.2,0.8 0.8,0.9" KeyTime="100%"/>


    </DoubleAnimationUsingKeyFrames>
   </SetterTimeline>

   <!-- Animates the vertical position of the second ball.
               Two animations are used. -->
   <SetterTimeline TargetName="twoAnimationsBall" Path="(Canvas.Top)">
    <DoubleAnimationUsingKeyFrames Duration="0:0:1.5" AutoReverse="True" RepeatBehavior="Forever"
       DecelerationRatio="1" >
     <SplineDoubleKeyFrame Value="190" KeySpline="0.2,0.8 0.8,0.9" KeyTime="100%"/>


    </DoubleAnimationUsingKeyFrames>
   </SetterTimeline>

   <!-- Animates the vertical position of the third ball.
               Three animations are used. -->
   <SetterTimeline TargetName="threeAnimationsBall" Path="(Canvas.Top)">
    <ParallelTimeline Duration="0:0:6" RepeatBehavior="Forever">

     <DoubleAnimationUsingKeyFrames Duration="0:0:6" AutoReverse="False" RepeatBehavior="Forever"
        DecelerationRatio="1" >
      <DoubleAnimationUsingKeyFrames.KeyFrames>
       <SplineDoubleKeyFrame Value="190" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:01.5"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.7,0.0 0.7,0.2" KeyTime="00:00:03"/>
       <SplineDoubleKeyFrame Value="250" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:04"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.7,0.0 0.7,0.2" KeyTime="00:00:05"/>
       <SplineDoubleKeyFrame Value="310" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:05.5"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.8,0.0 0.9,0.2" KeyTime="00:00:06"/>
      </DoubleAnimationUsingKeyFrames.KeyFrames>

     </DoubleAnimationUsingKeyFrames>
    </ParallelTimeline>
   </SetterTimeline>

  </ParallelTimeline>


 </Page.Storyboards>

 <Canvas Height="480" Width="640"
>

 


  <!-- The first bouncing ball. A single animation is used. -->
  <Ellipse Name="singleAnimationBall"
   Width="100"
   Height="100"
   Canvas.Left="50"
   Canvas.Top="380"
   Fill="{StaticResource redBallBrush}">

  </Ellipse>

  <!-- The second bouncing ball. Two animations are used. -->
  <Ellipse Name="twoAnimationsBall"
   Width="100"
   Height="100"
   Canvas.Left="250"
   Canvas.Top="380"
   Fill="{StaticResource orangeBallBrush}">
  </Ellipse>

  <!-- The third bouncing ball. Three animations are used. -->
  <Ellipse Name="threeAnimationsBall"
   Width="100"
   Height="100"
   Canvas.Left="450"
   Canvas.Top="380"
   Fill="{StaticResource blueBallBrush}">
  </Ellipse>

 </Canvas>
</Page>

So, the blue ball, which bounces three times, has the following animation:

   <SetterTimeline TargetName="threeAnimationsBall" Path="(Canvas.Top)">
    <ParallelTimeline Duration="0:0:6" RepeatBehavior="Forever">

     <DoubleAnimationUsingKeyFrames Duration="0:0:6" AutoReverse="False" RepeatBehavior="Forever"
        DecelerationRatio="1" >
      <DoubleAnimationUsingKeyFrames.KeyFrames>
       <SplineDoubleKeyFrame Value="190" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:01.5"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.7,0.0 0.7,0.2" KeyTime="00:00:03"/>
       <SplineDoubleKeyFrame Value="250" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:04"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.7,0.0 0.7,0.2" KeyTime="00:00:05"/>
       <SplineDoubleKeyFrame Value="310" KeySpline="0.2,0.8 0.8,0.9" KeyTime="00:00:05.5"/>
       <SplineDoubleKeyFrame Value="380" KeySpline="0.8,0.0 0.9,0.2" KeyTime="00:00:06"/>
      </DoubleAnimationUsingKeyFrames.KeyFrames>

     </DoubleAnimationUsingKeyFrames>
    </ParallelTimeline>
   </SetterTimeline>

  </ParallelTimeline>

You can that a KeyFrame collection is created with a bunch of SplineDoubleKeyFrames.  The KeySpline property is where the all important and powerful Bezier curve is articulated.  Now, you might be wondering, how the heck to you know how to specify the control points?  How do you know to put "0.8,0.0 0.9,0.2" to create the effect of gravity? How do you visualize time as a Bezier curve?  Stay tuned -- I've got a solution!