Introduction
While Storyboard animation techniques are rich enough in Silverlight, there are still a few shortcomings. This article explains how we can overcome them by
combining/twisting/hacking them cleverly. The result is Silverlight can generate animation effects like the Google Doodle
posted by Google on October 2011 and National Geographic channel’s Test your brain episode quite easily.
Most of the animations are done through code.
Background
The reader must be reasonably familiar with Storyboard, PlaneProjection, and other basic concepts in Silverlight.
Using the code
The application consists of a Main Page with a splitter control splitting the page into two horizontal parts. The top part contains several buttons, which
when clicked will take the user to a page demonstrating the said animation.
The code is developed in C# with Visual Studio 2010 Express edition.
Let us start with the canvas animation page.
Canvas animation page
This page demonstrates how to move a ball (ellipse in our case) inside a canvas that rebounds off the edges of the
canvas. One way to move an ellipse is to alter the margin property. Unfortunately, Silverlight does not have a thickness animation class.
The storyboard though has an auto reverse property; it might be very difficult to have random perpetual motion like a bouncing ball.
To achieve this, I have adopted a timer function to do the needful. The logic behind the page is that on every call to the timer function, the current thickness
is updated (based on dxCircle
and dyCircle
) depending on where the ball is with respect to the boundaries of the
canvas. After hitting a boundary, the signs of dxCircle
and/or dyCircle
are changed to simulate a rebound. Simultaneously,
the origin of LayoutRoot
’s opacity mask’s radial brush is moved to give a rebounding glow effect.
This page also has two types of free hand drawing that can be done quite easily. The code is quite self explanatory.
Bounce animation page
This page simulates a bouncing ball in 3-dimension. Clicking on the canvas, a ball will appear out of nowhere and bounce towards the viewer.
Any type of bouncing has two parts attached within: a vertical motion, in our case dropping from a point in the y Axis, and a horizontal motion, in our case
the movement on the z axis towards the viewer. The z axis motion is done by moving the projection of the ellipse’s (PlaneProjection) LocalOffsetZ
forward
(from 0 to 750). And the y axis motion is achieved by altering the margin’s top of the ellipse. Like before, since Silverlight does not have a thickness
animation class, the margin of the ellipse is altered through a slider, as shown below.
private void sliderY_ValueChanged(object s, RoutedPropertyChangedEventArgs<double> e)
{
Thickness thick = myEllipse.Margin;
thick.Top = (double)sliderY.Value;
myEllipse.Margin = thick;
}</double>
Now if I animate the slider’s value property between its Minimum
and Maximum
values, it will in turn end up animating the ellipse’s margin property thus
achieve the bouncing effect. Hold on, we are not there yet, the bounce simulation is still left.
Both the horizontal and vertical motion is captured in their respective slider’s ValueProperty
. The DoubleAnimation
object corresponding to the slider which
corresponds to the ellipse’s horizontal motion is attached to a CircleEase
, while the DoubleAnimation
object corresponding to the slider which corresponds
to the ellipse’s vertical motion is attached to a BounceEase
. That’s it, that does it all. Let me explain how.
While the horizontal motion is still in progress, BounceEase
kicks in and pushes the slider value to its maximum, then pulling it back briefly and again
pushing it to its maximum, simulating a bouncing ball effect. Watch the sliders closely to see the bounce animation in action.
Setting the BounceEase
’s Easingmode
property to
EaseOut
simulates gravity, the ball speeds up while approaching the floor and gradually slows while approaching
its next peak and continues in this fashion till it comes to a standstill.
A few others are also in order to add life to the animation:
- The shadow simultaneously narrows the gap between itself and the ellipse (shadow depth property shrinks as the animation proceeds).
- The blur value of the shadow also simultaneously reduces its value (blur radius property reduces as the animation proceeds).
- A radial brush simultaneously moves its origin and center from Point (0.5, 0) to Point (.5, 1) several times (again through a slider), simulating the roll of the ball.
Arc animation page
This page simulates a vibrating string, a pendulum of a clock, and a dribbling ball. The vibrating string is very similar to the Google
Doodle that Google displayed on Les Paul's 96th birthday in 2010. Here I demonstrate the same using Microsoft Silverlight.
Vibrating string
An arc has a start point, end point, and size property. The size determines how high the arc is to be drawn. It is enough to animate the height
of the size property to simulate a vibrating string. As before, I attach a slider to this property and animate the slider because there is no size animation
class. To achieve the to-and-fro motion of a vibrating string, I do:
- Set the storyboard’s double animation objects’
AutoReverse
property to true.
- Take the completed event handler of the storyboard.
In the completed event handler, the storyboard is first stopped and then I find out if the preset counter (nCounterArc2
, nCounterArc1
,
nCounterArc3
) is odd or even, and change the SweepDirection
of the arc accordingly. After this, I increment the counter
(nCounterArc2
, nCounterArc1
, nCounterArc3
) variable and reduce the slider’s Maximum
value by 5 to simulate dampening of the vibrating string.
This proceeds till the Maximum
value of the slider reaches zero, at which point the animation is completely stopped; if not, the animation is started again with the new
values. The code is presented below.
private void DoubleAnimation_Completed_XAML_Arc2(object sender, EventArgs e)
{
nCounterArc2++;
StBoardXAMLArc2.Stop();
if ((nCounterArc2 % 2) == 0)
myArc2.SweepDirection = SweepDirection.Clockwise;
else
myArc2.SweepDirection = SweepDirection.Counterclockwise;
if (sliderHeightArc2.Maximum <= 5)
sliderHeightArc2.Maximum--;
else
sliderHeightArc2.Maximum -= 5;
if (sliderHeightArc2.Maximum <= 0)
{
StBoardXAMLArc2.Stop();
return;
}
StBoardXAMLArc2.Begin();
}
The pendulum animation code is quite similar to the vibrating string animation code.
Dribbling ball
This is just an optical illusion as demonstrated by National Geographic channel’s Test your
brain episode. This illusion has the following steps (if you watch closely, only the shadow dribbles and the ball does not dribble):
- The ellipse is skinned with a radial brush. The radial brush moves its
Origin
and
Center
from Point (0.5, 0) to Point (.5, 1) several times (again through a slider), simulating a ball roll.
- The ellipse’s projection points to a
PlaneProjection
object. The ellipse moves by changing its LocalOffsetYProperty
from -100 to 1000.
- The dribbling effect is achieved by oscillating its
Dropshadow
object’s ShadowDepth
and BlurRadius
. This is also done through a slider.
Circle animation page
This page shows how circles can be grouped and animated together. In the constructor, a group of ellipses is created
with random fill Radialgradient
brushes. Each is given a rotation about its Z-axis with the CenterofRotationX
moved to 3 units. This displays all the
ellipses in a circular fashion. Each slider in the page is responsible for one property, like width, height, CenterofRotationX, RotationZ of the ellipse that
are animated together in one storyboard resulting in the effect.
Note: I have kept the sliders visible to give the developer a clear understanding of the animation; of course, in a production scenario, that would be hidden.
There are a few lines of commented code, you can open the comments and simulate other symmetric animations.