This post is a warm up after a long absence. I needed to quickly create a “Coming soon” page for my new company website and didn’t want it to be something static, so I’ve create a nice text animation that “swishes” into your screen.
This post isn’t entirely for beginners, you do need to have basic knowlege in C#, Silverlight and Microsoft expression blend. You can download the project file without the animation here, or the final one here.
We’ll start with a nice dark scene I made in Microsoft expression blend, it has a gradient to create depth and our text and a nice “floor” reflection:
And here is how our elements tree looks like:
You will notice that instead the our top container we have a Rectangle called Floor, and we packed our text (TheText) and its reflection (Reflection) inside a Grid.
Before we start animating I’m going to do two things:
1. Change the skew on the X axis of TheText and of Reflection to 30 and –30 respectively:
2. Move the text outside the visible area of the User Control.
Basically our text is going to travel all the way into the middle of the control where it will “slam” into an invisible wall and shake as a result of the impact. The text tilt (or skew) helps in maintaining the illusion that the text is being forcibly pushed into the screen by a force exerted on its lower parts.
The first order of business is to move the text container towards the center of the scene, and the movement most appear fast (swishy), I’ve allotted 0.5 seconds for this movement and translated the text 290 pixels (or, device-independent units that are approximately 1/96 inch) to the right.
Now I need to animated the “slam” and the post “slam” vibrations, I’ve achieved this by animating the text position back and forth slightly and also skewing it back and forth.
One important note: the keyframe at time index 0:00.500 contains 3 property changes, one for the translation of the grid into the visible area of the control, and 2 more for a change in the text and reflection’s skew property. You’ll notice that in that keyframe I’ve completely flipped the skew, turning the text skew to –30 and the reflection to 30 (the reflection will always be opposite to the text, since its, well, a reflection ;) ). This helps make the “slam” effect more real.
I also need to modify the way the skew property is changed over time, we call this Keyframe interpolation. By default our interpolation will be a Linear interpolation which changes the property value in equal increments between keyframes 0:00.000 and 0:00.500. This is not a good behavior for us, instead I’ll modify by checking the Hold In option from the popup menu; Hold In (I think, formerly known as hold out) will not interpolate changes over time; instead, it makes an abrupt change to the new property value when the playhead (or simply, the animation) reaches the keyframe where the change occurs.
So now we have our “slam” and we need to tend to the vibrations. I’ve allotted 0.6 seconds for the post impact/slam vibrations, Within this time frame we’re gonna shake that text pretty good.
There are 6 keyframes between keyframe 0:00.500 and 0:01.100, in each of those I’ve moved (translated) the text container (grid containing the text and the reflection) between 280 to 290 pixels, like this:
|Keyframe ||Value |
|0:00.600 ||283 |
|0:00.700 ||290 |
|0:00.800 ||286 |
|0:00.900 ||290 |
|0:01.000 ||289 |
|0:01.100 ||290 |
Blend will adjust your values slightly (e.g 290 may turn into 289.945) and that is perfectly alright. If we wouldn’t have skewed the test, this animation alone would have provided a nice impact/slam effect, however with the skew it looks even better (IMHO of course). This is how I animated the skew over our allotted slam time frame:
|TheText ||Reflection |
|Keyframe ||Value |
|0:00.600 ||20 |
|0:00.700 ||-20 |
|0:00.800 ||10 |
|0:00.900 ||-10 |
|0:01.000 ||5 |
|0:01.100 ||0 || |
|Keyframe ||Value |
|0:00.600 ||-20 |
|0:00.700 ||20 |
|0:00.800 ||-10 |
|0:00.900 ||10 |
|0:01.000 ||-5 |
|0:01.100 ||0 |
Here is another look at the elements tree and the storyboard timeline:
Now we’re left with one thing to do, we need to start the animation when the control is loaded and visible:
public partial class Page : UserControl
this.Loaded += new RoutedEventHandler(Page_Loaded);
void Page_Loaded(object sender, RoutedEventArgs e)
That’s it, we’re done. Here is the end result: