Thursday, January 27, 2011

Easy tweening...

Here we go again...
During my html5 canvas expedition i found this neat little library named tween.js which is a javascript implementation of the easing functions of Robert Penner.
Easing functions allow you to apply custom mathematical formulas to your animations. 
In the first version of the canvas steelseries gauges i used the trident.js library of Kirill Grouchnikov which is a nice animation lib that also supports easing.
Because i only needed the interpolation between two values over a specific time i was looking for something smaller which was the reason why i moved from trident.js to tween.js.


But i won't talk about html5 canvas and javascript again but more about java...
When i took a look at the 12kb small tween.js script i liked the approach and thought about porting this functionality to java.


Like i said i was looking for a small library that interpolates values nothing more and so i created the Easy lib.
I know that one should avoid reinventing the wheel over and over again but to better understand an animation library it was a good thing to do that.


So the Easy class takes the following parameters:

(optional) object (Object)   : the object that you would like to "animate"
(optional) property (String) : the property which setter you would like to use
(mandatory) start (double)   : the value where the interpolation should start
(mandatory) stop (double)    : the value where the interpolation should stop
(mandatory) duration (long)  : the time in [ms] the interpolation should take
(optional) easing (enum)     : the easing function it should use to interpolate

So there are the following constructors available in Easy.class Ease.class:

Ease(Object OBJECT, String PROPERTY)


Ease(double START, double STOP, long DURATION)
    
Ease(double START, double STOP, long DURATION, EasingFunction EASING_FUNCTION)
        
Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION)
    
Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, EasingFunction EASING_FUNCTION)


Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, Color START_COLOR, Color STOP_COLOR)



Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, Color START_COLOR, Color STOP_COLOR, EasingFunction EASING_FUNCTION)

The following easing functions are available:



    EASE_BACK_IN
    EASE_BACK_OUT
    EASE_BOUNCE_IN
    EASE_BOUNCE_OUT
    EASE_BOUNCE_IN_OUT
    EASE_CIRCULAR_IN
    EASE_CIRCULAR_OUT
    EASE_CIRCULAR_IN_OUT
    EASE_CUBIC_IN
    EASE_CUBIC_OUT
    EASE_CUBIC_IN_OUT
    EASE_EXPONENTIAL_IN
    EASE_EXPONENTIAL_OUT
    EASE_EXPONENTIAL_IN_OUT
    EASE_LINEAR
    EASE_QUADRATIC_IN
    EASE_QUADRATIC_OUT
    EASE_QUADRATIC_IN_OUT (DEFAULT if nothing is provided)
    EASE_QUART_IN
    EASE_QUART_OUT
    EASE_QUART_IN_OUT
    EASE_QUINTIC_IN
    EASE_QUINTIC_OUT
    EASE_QUINTIC_IN_OUT
    EASE_SINE_IN
    EASE_SIN_OUT
    EASE_SIN_IN_OUT
    EASE_STRONG_IN,
    EASE_STRONG_OUT
    EASE_STRONG_IN_OUT

You will find them in eu.hansolo.easy.EasingFunction


UPDATE:
Please find here an easing function generator that will show you the graphs of the different functions and also gives you an idea how to create those functions.


How does it work...?


The Ease class fires EaseEvents and EaseColorEvents. To receive this events you could attach a EaseEventListener to the Ease class. Each EaseEvent provides a value, a state and a color.
So if you don't provide a object with it's property the Ease class will only interpolate between the start and stop value in the given time with the given easing function. If you would like to use the values calculated by the easing function you have to attach the EaseEventListener to the Ease class instance and handle the values in the easeEventPerformend() method of the handler.

Whereas if you provide a object with it's property the Ease class instance will invoke the setProperty() method of the object and set the interpolated value directly.


The Ease class will not take care about repaints of dirty areas etc. but only calculate the values and fire events...that's all.


Here is a simple example on how to use the Easy lib:



// The class with the property we would like to interpolate
public class InvokedClass
{
    private double value;


    public InvokedClass()
    {
        value = 0;
    }


    public double getValue()
    {
        return value;
    }


    public void setValue(double value)
    {
        this.value = value;
    }
}

// The class where the interpolation is defined and started from


public class EasyTest
{        
    public static void main(String[] args)
    {
        final InvokedClass invokeInstance = new InvokedClass();


        Ease ease = new Ease(invokeInstance, "value", 0, 25, 5000);
        ease.addEaseEventListener(new EaseEventListener()
        {
            @Override
            public void easeEventPerformed(EaseEvent event)
            {
                System.out.println(invokeInstance.getValue());
            }
        });
        ease.start();
    }
}



This simple example will output the values from 0 to 25 interpolated by a QUADRATIC_IN_OUT easing function (which is the default) within 5 sec.


This might not be the best implementation but for me it was fun and maybe it's of use for one or another...


See it in action here...


Please find the downloads here:


    The binary jar file
    The netbeans project


The files will change from time to time because i'm still adding features to the library.


Keep coding...

2 comments:

  1. The netbeans zip file seems to be broken. On OSX Snow Leopard I can't unzip it. I've tried unzip, gunzip, tar, jar. Some part work, but always get errors.

    sorbus

    ReplyDelete
  2. Ups...sorry for that...should work now...

    ReplyDelete