Click here to Skip to main content
16,015,218 members
Articles / Programming Languages / C#

Silverlight: Creating a simple smooth reverse storyboard animation on mouse enter and leave

Rate me:
Please Sign up or sign in to vote.
3.00/5 (1 vote)
8 Sep 2009CPOL2 min read 17.9K   4  
I have seen this question come up a lot and did not come accross a simple answer. Perhaps I just wasn't looking hard enough!

Introduction

I have seen this question come up a lot and did not come across a simple answer. Perhaps, I just wasn't looking hard enough! But any how, I thought I would share my experience. This was the very first thing I tried to do in Silverlight and although I knew what I needed to do conceptually, I struggled finding my way around a little. However, I got there after a couple of hours. Hopefully, this will get people going a lot quicker than I did!

If you want to see the code and run the sample, you can download the solution from above!

I started by creating a user control in Blend which I encapsulated all my behavior into. I then created my mouse enter Storyboard which I will not go into in too much detail. The XAML is given below:

XML
<Storyboard x:Name="flipforward" Duration="00:00:03">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="userControl"
 Storyboard.TargetProperty="(UIElement.Projection)
.(PlaneProjection.RotationY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="45"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="25"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>

I then used Blend to create a copy of this and used the reverse command in Blend to, you guessed it, reverse the Storyboard! Which looks like this:

XML
<Storyboard x:Name="flipback" Duration="00:00:03">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="userControl"
Storyboard.TargetProperty="(UIElement.Projection)
.(PlaneProjection.RotationY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="25"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="45"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>

In the code-behind of my user control (of course, you should try to avoid using code-behind in production code!), I override the mouse enter and leave events with the following code:

C#
protected override void OnMouseEnter(MouseEventArgs e)
{
   var flipstoryboard = Resources["flipforward"]
    as Storyboard;
   if (flipstoryboard != null) flipstoryboard.Begin();
}

protected override void OnMouseLeave(MouseEventArgs e)
{
  var forwardstoryboard = Resources["flipforward"]
    as Storyboard;
  var flipstoryboard = Resources["flipback"] as Storyboard;
  if (flipstoryboard != null &&
  forwardstoryboard != null)
  {
    var duration = flipstoryboard.Duration;
    flipstoryboard.Begin();
    flipstoryboard.Seek(
      duration.TimeSpan -
      forwardstoryboard.GetCurrentTime());
  }
}

The mouse enter event simply gets a reference to my enter Storyboard and begins it. The mouse leave event needs to do a bit more efficient since we want the reverse animation to be smooth. If we just called the Begin method, the reverse animation would play from the start which would make it look jumpy if you moved the mouse away before the first Storyboard completed. What we need to do is find out where the first Storyboard currently is and fast forward the reverse animation to the same point.

I hope this was helpful.

This article was originally posted at http://www.sunmetablog.co.uk?p=208

License

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


Written By
Software Developer
United Kingdom United Kingdom
We cannot achieve perfection but we can strive for excellence. Excellence through creativity that pushes innovation, collaboration that facilitates productivity, knowledge that empowers people and persistence that eventually pays off !

Enjoy what you do and do what you enjoy !

Comments and Discussions

 
-- There are no messages in this forum --