Skip to main content

Microsoft Silverlight

Unanswered Question Silverlight - Tweening Class codeRSS Feed

(0)

Harvey
Harvey

Member

Member

34 points

15 Posts

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

simsod
simsod

Member

Member

46 points

24 Posts

Re: Silverlight - Tweening Class code

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

mano1
mano1

Member

Member

10 points

5 Posts

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!

Harvey
Harvey

Member

Member

34 points

15 Posts

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
 

liquidboy
liquidboy

Member

Member

270 points

62 Posts

Silverlight MVP

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!

jernej
jernej

Member

Member

10 points

6 Posts

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

mchlsync
mchlsync

Star

Star

14606 points

2,730 Posts

Silverlight MVP

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

Regards,
Michael Sync
Silverlight MVP

Blog : http://michaelsync.net


jernej
jernej

Member

Member

10 points

6 Posts

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

Ryoushin
Ryoushin

Member

Member

37 points

21 Posts

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 - Sator Arepo Tenet Opera Rotas.

mchlsync
mchlsync

Star

Star

14606 points

2,730 Posts

Silverlight MVP

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

Regards,
Michael Sync
Silverlight MVP

Blog : http://michaelsync.net


Ryoushin
Ryoushin

Member

Member

37 points

21 Posts

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 - Sator Arepo Tenet Opera Rotas.
  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities