Skip to main content
Home Forums Silverlight Programming Programming with .NET - General Silverlight - Tweening Class code
10 replies. Latest Post by Ryoushin on March 25, 2008.
(0)
Harvey
Member
34 points
15 Posts
05-15-2007 7:19 PM |
Hi,
Just wanted to contribute something back to the forums. I have created a tweening class which has been loosely based on some Javascript tweening classes. If you have any suggestions please post them here.
Credits go to http://jstween.blogspot.com/ and http://www.codeproject.com/csharp/tweencs.asp which provided some valuable starting points.
Note that I originally wrote this class for the standard windows forms library, just change the Tick implementation from the storyboard hack to a Forms Timer.
Still todo are implementing other tweens (color, text, etc tweens still to come).
And finally, Usage goes something like this ( check out the MotionType enum for other motions)..... Motion motion; private void init() { motion = new Motion(new Coordinate(0, 0), new Coordinate(100, 100), new TimeSpan(0, 0, 0,3), new TimeSpan(0, 0, 0, 0, 100), MotionType.BackEaseIn, this); motion.RaiseTickEvent +=new EventHandler(motion_RaiseTickEvent); } private void motion_RaiseTickEvent(Object sender, EventArgs e) { SomeControl.SetValue(Canvas.TopProperty, motion.Current.X); SomeControl.SetValue(Canvas.LeftProperty, motion.Current.Y); }..... //---------------------------------- START CODE ------------------------------using System;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Ink;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;namespace Harveys.Tween{ public class Motion { private Coordinate start; private Coordinate end; private Coordinate current; private TimeSpan timeframe; private TimeSpan tickInterval; private TimeSpan currentInterval; private MotionType motion; private Control parent; private delegate double MotionFunction(double CurrentTime, double BeginState, double ChangeState, double Duration); private MotionFunction func; public Motion(Coordinate Start, Coordinate End, TimeSpan Timeframe, TimeSpan TickInterval, MotionType Motion, Control Parent) { start = Start; end = End; current = start; timeframe = Timeframe; tickInterval = TickInterval; motion = Motion; parent = Parent; func = (MotionFunction)Delegate.CreateDelegate(typeof(MotionFunction), typeof(Tweener).GetMethod(Motion.ToString())); parent.Loaded += new EventHandler(InitTick); } // Start Tick private void InitTick(Object sender, EventArgs e) { Storyboard timerTimeline = new Storyboard(); timerTimeline.Duration = new Duration( tickInterval ); parent.Resources.Add(timerTimeline); timerTimeline.Begin(); timerTimeline.Completed += new EventHandler(Tick); } private void Tick(Object sender, EventArgs e) { // Set current time and check is stop is required! currentInterval += tickInterval; if (currentInterval < timeframe) ((Storyboard)sender).Begin(); // Raise the Tick Event OnRaiseTickEven(new EventArgs()); } // Coordinate Changes Event public delegate void OnTickEventHandler(Object sender, EventArgs e); public event EventHandler RaiseTickEvent; protected virtual void OnRaiseTickEven(EventArgs e) { EventHandler handler = RaiseTickEvent; if (handler != null) { handler(this, e); } } public Coordinate Current { get { double t = (double)currentInterval.TotalMilliseconds / 1000.0; double d = (double)timeframe.TotalMilliseconds /1000.0; current.X = func(t, start.X, end.X - start.X, d); current.Y = func(t, start.Y, end.Y - start.Y, d); return current; } } } public enum MotionType { RegularEaseIn, RegularEaseOut, RegularEaseInOut, StrongEaseIn, StrongEaseOut, StrongEaseInOut, BackEaseIn, BackEaseOut, BackEaseInOut, ElasticEaseIn, ElasticEaseOut, ElasticEaseInOut, BounceEaseOut, BounceEaseIn, BounceEaseInOut } public struct Coordinate { private double x, y; public Coordinate(double X, double Y) { x = X; y = Y; } public double X { get { return x; } set { x = value; } } public double Y { get { return y; } set { y = value; } } } class Tweener { // t = Currrent Timeline Position (Seconds) // b = Begining Value // c = Relative Change ( Final Value - Begining Value ) // d = Final Timeline Value (Seconds) public static double BackEaseIn(double t, double b, double c, double d) { double s = 1.70158; return c*(t/=d)*t*((s+1)*t - s) + b; } public static double BackEaseOut(double t, double b, double c, double d) { double s = 1.70158; return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; } public static double BackEaseInOut(double t, double b, double c, double d) { double s = 1.70158; if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; } public static double ElasticEaseIn(double t, double b, double c, double d) { double s, p, a; p = d * .3; a = c; s = p / 4; if (t==0) return b; if ((t/=d)==1) return b+c; else s = p/(2*Math.PI) * Math.Asin(c/a); return -(a*Math.Pow(2,10*(t-=1)) * Math.Sin( (t*d-s)*(2*Math.PI)/p )) + b; } public static double ElasticEaseOut(double t, double b, double c, double d) { double s, p, a; p=d*.3; a = c; s = p / 4; if (t==0) return b; if ((t/=d)==1) return b+c; else s = p/(2*Math.PI) * Math.Asin (c/a); return (a*Math.Pow(2,-10*t) * Math.Sin( (t*d-s)*(2*Math.PI)/p ) + c + b); } public static double ElasticEaseInOut(double t, double b, double c, double d) { double s, p, a; p=d*(.3*1.5); a=c; s=p/4; if (t==0) return b; if ((t/=d/2)==2) return b+c; else s = p/(2*Math.PI) * Math.Asin (c/a); if (t < 1) return -.5*(a*Math.Pow(2,10*(t-=1)) * Math.Sin( (t*d-s)*(2*Math.PI)/p )) + b; return a*Math.Pow(2,-10*(t-=1)) * Math.Sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; } public static double BounceEaseOut(double t, double b, double c, double d) { if ((t /= d) < (1 / 2.75)) { return c * (7.5625 * t * t) + b; } else if (t < (2 / 2.75)) { return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; } else if (t < (2.5 / 2.75)) { return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; } else { return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; } } public static double BounceEaseIn(double t, double b, double c, double d) { return c - Tweener.BounceEaseOut(d - t, 0, c, d) + b; } public static double BounceEaseInOut(double t, double b, double c, double d) { if (t < d / 2) return Tweener.BounceEaseIn(t * 2, 0, c, d) * .5 + b; else return Tweener.BounceEaseOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b; } public static double StrongEaseInOut(double t, double b, double c, double d) { return c * (t /= d) * t * t * t * t + b; } public static double RegularEaseIn(double t, double b, double c, double d) { return c*(t/=d)*t + b; } public static double RegularEaseOut(double t, double b, double c, double d) { return -c * (t /= d) * (t - 2) + b; } public static double RegularEaseInOut(double t, double b, double c, double d) { if ((t /= d / 2) < 1) return c / 2 * t * t + b; return -c / 2 * ((--t) * (t - 2) - 1) + b; } public static double StrongEaseIn(double t, double b, double c, double d) { return c * (t /= d) * t * t * t * t + b; } public static double StrongEaseOut(double t, double b, double c, double d) { return c * ((t = t / d - 1) * t * t * t * t + 1) + b; } public static double strongEaseInOut(double t, double b, double c, double d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b; return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; } } }//---------------------------------- END CODE ------------------------------
simsod
46 points
24 Posts
05-16-2007 7:19 AM |
Nice work, will definitly try this out when I get the time!
mano1
10 points
5 Posts
05-17-2007 1:30 AM |
Good job!
Why not add it to the gallery?
Perhaps the name "Gallery" scares some people away... You should see it as a "samples database" ... the place to post all of your SL projects to share with the community so everyone can learn and accelerate their SL projects.
thanks!
05-17-2007 2:34 AM |
Mano,
Thats a good suggestion, after I add some graphical demonstrations of the class will add it to the gallery.
Cheers,Harvey
liquidboy
270 points
62 Posts
01-13-2008 9:49 PM |
Have you taken this any further than where it is now? This is great and i was looking at doing something similar (like the tweener library for flash)
Well done!
jernej
6 Posts
03-12-2008 5:26 AM |
All the examples published on http://home.exetel.com.au/thesandpit/ worked when i had SL 1.1 installed, since I got SL 2 they don't work anymore :(
mchlsync
Star
14606 points
2,730 Posts
03-12-2008 5:47 AM |
jernej:All the examples published on http://home.exetel.com.au/thesandpit/ worked when i had SL 1.1 installed, since I got SL 2 they don't work anymore :(
Yes. SL 1.1 doesn't compatible with SL 2 beta1. You have to convert your project from 1.1 to 2.
03-12-2008 11:48 AM |
Hi, I successfully ported the Tweener Block application, but I'm having some problems with Tweener Dooby. Has anyone already ported this solution so that it works in SL 2?
Thanks
Ryoushin
37 points
21 Posts
03-25-2008 5:23 AM |
Hi all,I've built my personal version of Tweener which supports Silverlight 2.0.There's also Stop, Pause, Resume, Rewind logic together with Yoyo behavior and it targets any DependencyProperty of numeric type, Color type and Point type.It also tweens RenderTransform affine transformations provided by SL (SKew, Rotate, Scale, Translate...)
Source code, documentation e library can be downloaded from here:http://www.pacem.it/CMerighi/Posts/68,en-US/Silverlight_2.0_Tweener(Of_T)_Ultimate_Version.aspx
Hope it helps.
03-25-2008 11:12 AM |
great.. thanks.. I tried to write a comment in your post but captcha: is really suck.. it keep on showing "wrong code" I tried C19G4, Cl9G4, CL9G4, C/9G4 and C|9G4 but keep on showing "wrong code".. :( it makes me angry now.
03-25-2008 2:51 PM |
...lol... that is a captcha of mine It comprehends punctuations, lower and upper chars... so it isn't probably always readable ...err ...even for a human being!I'd love to have feedbacks on my blog post, if the captcha isn't readable enough you can always roll the dice and refresh the page...Sorry for the inconvenience though, but thank you for appreciating...