This is a very interesting sample suggested by Karthik. He asked if it is possible to reverse an animation created by Storyboard. He provided me a rotating cube created by Swift3D (In the latest version, it supports exporting 3D animation to XAML) and my task is to make it alive.
Besides, the animation speed can be controlled by the mouse movement as well. (Try to drag over the screen.)
Since Storyboard Animation and Timeline Animation are completely different, the approach on reversing the animations differs as well.
Vote for this sample
Comparison
Flash implementation: 40 minutes
Silverlight implementation: 180 minutes (Implemented First)
What’s the difference?
- Reverse Animation: gotoAndStop [AS3] vs Storyboard.Seek [C#]
Source codes
Rotating Cube [Flash 9, AS3] (54.7 KiB, 614 hits)
Rotating Cube [Silverlight 2, C#] (42.3 KiB, 641 hits)
Flash
Silverlight
Reverse Animation: gotoAndStop [AS3] vs Storyboard.Seek [C#]
By using gotoAndStop and Timer Class together, it’s not difficult to reverse the animations. Let’s take a look on the sample below.
// AS3
// get the cube animation from the stage
var _cube:MovieClip = getChildByName("cube") as MovieClip;
// animation movement speed
var _speed = 25;
// moving direction: 1 = normal, -1 = reverse
var _sign = -1;
var _timer:Timer = new Timer(_speed);
_timer.addEventListener(TimerEvent.TIMER, on_timer);
_timer.start();
private function on_timer(e : TimerEvent):void{
// get the target frame
var _currentFrame:int = _cube.currentFrame + _sign;
if(_currentFrame > _cube.totalFrames){
_currentFrame = 0;
}else if(_currentFrame <= 0){
_currentFrame = _cube.totalFrames;
}
// animate the movieclip
_cube.gotoAndStop(_currentFrame);
}
// change the speed of the animation
_timer.delay = newValue;
However, I got a nightmare in C#. The Seek method simply doesn’t work if you set a position less than the previous value. After many attempts, I got the solution finally.
The code is a little bit strange, but it just work. If you have a better approach, please let me know.
// C#
// start the enter frame event
Dispatcher _timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0, 0, 0, 0, 40);
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
// Rotation is the Storyboard
Rotation.Begin();
Rotation.Pause();
// Speed
int _speed = 40; // or -40 to make it reverse
// Seek Position
TimeSpan _timeSpan = new TimeSpan();
// Animation length
TimeSpan _maxTimeSpan = new TimeSpan(0, 0, 10);
void _timer_Tick(object sender, EventArgs e)
{
if (_speed >= 0)
{
// Increase the seek position
_timeSpan += new TimeSpan(0, 0, 0, 0, _speed);
// if it reached to maximum, set it to 0
if(_timeSpan.Ticks > _maxTimeSpan.Ticks){
_timeSpan = new TimeSpan();
Rotation.Seek(_timeSpan);
}
else
{
// Decrease the seek position
_timeSpan -= new TimeSpan(0, 0, 0, 0, Math.Abs(_speed));
// if it reached to 0, set it to maximum time
if (_timeSpan.TotalMilliseconds < 0)
_timeSpan = new TimeSpan(_maxTimeSpan.Ticks);
// Hacking for reverse
Rotation.Stop();
Rotation.Begin();
Rotation.Seek(_timeSpan);
Rotation.Pause();
}
}