Silverlight - Tweening Class code
Last post 03-25-2008 2:51 PM by Ryoushin. 10 replies.
Sort Posts:
05-15-2007 7:19 PM
Silverlight - Tweening Class code

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 ------------------------------

Harvey

Loading...
Joined on 05-04-2007
Posts 15
05-16-2007 7:19 AM
Re: Silverlight - Tweening Class code

Nice work, will definitly try this out  when I get the time!

simsod

Loading...
Joined on 05-01-2007
Posts 24
05-17-2007 1:30 AM
Re: Silverlight - Tweening Class code

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!

mano1

Loading...
Joined on 09-19-2002
Posts 5
05-17-2007 2:34 AM
Re: Silverlight - Tweening Class code

Mano,

 Thats a good suggestion, after I add some graphical demonstrations of the class will add it to the gallery.

Cheers,
Harvey
 

Harvey

Loading...
Joined on 05-04-2007
Posts 15
01-13-2008 9:49 PM
Re: Silverlight - Tweening Class code

Hi,

 

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!

Learn SilverLight with me!

liquidboy

Loading...
Joined on 08-08-2006
Sydney
Posts 54
03-12-2008 5:26 AM
Re: Silverlight - Tweening Class code

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 :(

jernej

Loading...
Joined on 03-04-2008
Posts 6
03-12-2008 5:47 AM
Re: Silverlight - Tweening Class code

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.  

(If this has answered your question, please click on "Mark as Answer" on this post. Thank you!)

Best Regards,
Michael Sync

Blog : http://michaelsync.net
Feed : http://michaelsync.net/feed

mchlSync

Loading...
Joined on 09-16-2005
Singapore
Posts 2,295
03-12-2008 11:48 AM
Re: Silverlight - Tweening Class code

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

jernej

Loading...
Joined on 03-04-2008
Posts 6
03-25-2008 5:23 AM
Re: Silverlight - Tweening Class code

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.

Ryoushin - It is not knowledge, but the act of learning which grants the greatest enjoyment.

Ryoushin

Loading...
Joined on 08-04-2006
Parma, IT
Posts 19
03-25-2008 11:12 AM
Re: Silverlight - Tweening Class code

 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.

 

(If this has answered your question, please click on "Mark as Answer" on this post. Thank you!)

Best Regards,
Michael Sync

Blog : http://michaelsync.net
Feed : http://michaelsync.net/feed

mchlSync

Loading...
Joined on 09-16-2005
Singapore
Posts 2,295
03-25-2008 2:51 PM
Re: Silverlight - Tweening Class code

...lol... that is a captcha of mine Embarrassed
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...

Ryoushin - It is not knowledge, but the act of learning which grants the greatest enjoyment.

Ryoushin

Loading...
Joined on 08-04-2006
Parma, IT
Posts 19
Page view counter