Universal Tween Engine

Introduction

The Universal Tween Engine enables the interpolation of every attributes from any object in any Java project (being Swing, SWT, OpenGL or even console-based). A tween is a static animation running for a fixed amount of time. Therefore, tweens are perfect candidates to animate your UIs, splash screens, and all the static animations of your characters. A tween can animate anything: position, rotation, opacity, color, scale, etc. The only limitation of the tween engine is your imagination.

Demos

Features

  • Zero allocation! Use your project safely on Android without fearing the garbage collector!
  • Supports every interpolation function defined by Robert Penner: http://www.robertpenner.com/easing/
  • Can be used with any object. You just have to implement the TweenAccessor interface when you want interpolation capacities.
  • Every attributes can be interpolated. The only requirement is that what you want to interpolate can be represented as a float number.
  • One line is sufficient to create and start a simple interpolation.
  • Tweens can be easily sequenced thanks to Timelines.
  • Tweens can act on more than one value at a time, so a single tween can change the whole position (X and Y) of a sprite for instance !
  • Tweens and Timelines can be repeated, with a yoyo style option.
  • Many callbacks can be specified (when tweens or timelines complete, start, end, etc.).
  • Simple timers can be built with Tween.call().
  • Source code extensively documented!
  • Wiki documentation to get you started!

The engine is mainly divided into Tweens and Timelines.

Tweens

Tweens are small one-line statements that let you start the animation of one or multiple attributes of an object. Better than a thousand lines of text, take a look at the following demo applet (link on the right). Don’t hesitate to change the easing function, and to add repetitions to your animation.

In this demonstration, we only use tween to animate the position of an object. However, when using the Tween Engine, you describe what you want to animate, so everything is possible. To start a tween, only thing needed is:

// Animation of an object position to the coordinates (100,200), in one second
Tween.to(myobject, Type.POSITION, 1.0f).target(100, 200).start(myManager);

Many options are available to customize the animation:

Tween.to(myobject, Type.POSITION, 1.0f)
    .targetRelative(10, -20)  // the target can be relative to the current values
    .delay(2.5f)              // a delay can be specified
    .ease(Quad.OUT)           // the easing function can be modified
    .repeat(2, 0.5f)          // repetitions are possible
    .repeatYoyo(2, 0.5f)      // yoyo repetitions too (one play forward, the other backward, etc)
    .setUserData(obj)         // custom objects can be attached
    .setCallback(cb)          // callbacks can be specified to get notified of the completion
    .setCallbackTriggers(...) // callbacks can be launched on many events, not just completion
    .start(myManager);

A tween is based on precise timings, as follows:

A tween under normal playing. It may start with a delay, and can be repeated any number of times (with an optional delay between repetitions).

Callbacks are very important, and let you trigger actions on precise events. There are callbacks for forward playing, and for backward playing:

You can get notified of many events, both during forward play and backward play!

Timelines

Timelines let you create powerful sequences of multiple tweens. They will be automatically delayed to be executed one after the other. See the following demo applet on the right.

Creating sequences is easy, just stack .push() calls! You can also nest timelines into other timelines.

Timeline.createSequence()
    .push(Tween.set(...)) // First, set all objects to their initial positions
    .push(Tween.set(...))
    .push(Tween.set(...))
    .pushPause(1000)      // Wait 1 second
    .push(Tween.to(...))  // Move the objects around, one after the other
    .push(Tween.to(...))
    .push(Tween.to(...))
    .beginParallel()      // Move them all at the same time now
        .push(Tween.to(...))
        .push(Tween.to(...))
        .push(Tween.to(...))
    .end()
    .repeatYoyo(2, 500)   // repeat the whole sequence 2 times
    .start(myManager);    // and finally start it!

The options of timelines are the same as the ones for tweens, including repetitions and callbacks! What was possible for tweens is also possible for timelines.

Download binaries and source code

The project is fully open-source, and currently hosted at Google Code using a Mercurial repository. Each time a revision is considered stable, it is released as a binary package.

Project page: http://code.google.com/p/java-universal-tween-engine/
Download page: http://code.google.com/p/java-universal-tween-engine/downloads/list

Get started

A detailed example is provided in the project wiki:
http://code.google.com/p/java-universal-tween-engine/wiki/GetStarted

Also, you may want to take a look at the source code of the demo:
http://code.google.com/p/java-universal-tween-engine/source/browse/#hg%2Ftween-engine-tests%2Fsrc%2Faurelienribon%2Ftweenengine%2Ftests

Javadoc

Sources for the library are shared within the zip file. Linking to them in your favorite IDE (eclipse, netbeans, idea) will let you access the javadocs directly from the editor itself.

Support

If you spotted a bug, or have a great improvement idea, feel free to submit it to the Issue Tracker.

For any other information, there is a dedicated forum for you.

68 Comments + Add Comment

  • [...] in order to present the library to new users, I wrote a new page dedicated to it (also available by clicking on its banner on the front page of this blog). The page features two [...]

  • Hi,

    Version 6.2.0:
    – No more .size() on TweenManager?

    Cheers

    • Hello. I removed it since its behavior was not coherent with its definition, but I’m planning to reintroduce it in a different way.

  • Hi,

    I am trying to build an app and facing issues with the delay and Timeline. Are there any constraints on the delay time values?
    Anyways, I cant get the timeline working. Any suggestions?

    Thanks

    • Well, I can’t really help you with your description of the issue :p
      One of the most common fix: are you sure all your timings use consistent time unit? I mean if the duration of a tween is expressed in milliseconds, then the duration of the delays and all other timings have to be expressed in milliseconds.

      I’ll try to setup a forum so you can explain your issue furthermore. Before that, send me a mail ;)

  • can you please make the android demo application’s code be available – it will help me to understand the implementations and get me started to zoom in and zoom out the layouts. thanks

  • Hey there,
    i am making a subtitling system in java.. i want my subtitles to have tweens like to make it bounce and stuff which i can later import..
    is it possible to get tweens on ur text using this engine??

    thanks!!

    • You can use the engine on everything, everywhere, that’s the spirit :)
      If you need help, make a post in the forum with code exctracts of what you’re trying to do.

      • Hey there.. quick question.. after adding tweens to the text i want to save the file as a subtitle file(.srt).. would the tweens be still there..??
        as far as i found.. (.srt) wouldn support animation..
        on the other hand .ass(advanced sub station aplha ) is used for more advanced metadata would that help?

        Thanks

  • [...] Universal Tween Engine integration with some Tweeners built in. [...]

  • I have problems getting the JavaDoc to work on an Android project. I tried to add the sources.jar to the Java Build Path, but I had no luck.

    Can you guide me please?

  • [...] silnika gry użyto Uniwersal Tween Engine, który odpowiada za animowanie elementów dekoracyjnych oraz animację samego robaczka. Biblioteka [...]

  • [...] silnika gry użyto Uniwersal Tween Engine, który odpowiada za animowanie elementów dekoracyjnych oraz animację samego robaczka. Biblioteka [...]

  • [...] la police de caractère avec Font Forge les sons avec Audacity, l’animation avec Universal Tween Engine et le moteur global du jeu avec Libgdx Le tout sous [...]

  • Hello, I think your web site might be having browser
    compatibility issues. Whenever I take a look at your site in Safari,
    it looks fine however when opening in Internet
    Explorer, it has some overlapping issues. I simply
    wanted to provide you with a quick heads up! Other than that, wonderful website!

  • Hello,

    How can I resize an object with animation?

    Cheers

  • Thank you for creating such a great tool~

    When playing around with Timeline,
    I wonder is there a way to replay established timeline?

    • Hello,
      First of all, thank to aurelien for this great job.
      I encountered the same problem I try to replay a timeline but nothing append. it seems to me that the philosophy of this framework is to create tween or timeline on the fly to be use only once, so reuse of already created animations is apparently not expected.
      After reading the source I found a workaround to restart a timeline once completed:
      In BaseTween.java in method start you can add these two lines:

      step=-2; //to pass isValid(step) conditions
      isFinished=false; //to avoid removing object on first update iteration if autoRemove is true see TweenManager.setAutoRemove

      After this patch, you can reuse an existing timeline simply with:
      mTimeline.start(mTweenManager);

      To reuse animation, I think that it’s better to set TweenManager.setAutoRemove(mTimeline,false);

      Mabye this patch can have some side effects, the best would be a feedback of aurélien.
      Best regards

      Valérian

      • I got the same problem and even with Tween.setAutoRemove set to false, it didn’t worked.
        Fortunately your solution worked, but I’m worried with side effecst too.
        Does aurélien is still developing the tool?

  • Hello,

    the TweenEngine is really great, I’m just learning how to use it. I have one question though: I want to make an object “fly in” from below. That does not seem to work, I suppose because the initial position of the object is a negative number. Is there any possbility to do that?

    I’d be happy to get an answer but want to thank you anyway for creating this great piece of software.

  • Thanks , I have recently been looking for info approximately this subject for ages and yours is the greatest I’ve discovered so far. But, what in regards to the bottom line? Are you sure concerning the supply?

  • Thank you for ones good writeup. It actually was a amusement account it. Glimpse advanced to far added agreeable from you! However, how can we communicate?

  • Fixed the date. Thanks.

  • The link to your forum is broke so I’ll ask here. Hopefully you can help

    I have two different things happening when I try to scale an image.

    First I set the initial scale to 0.25f, 0.25f

    When I try to tween it to the actual size of the image nothing is shown until it reaches the actual size.

    Then I tried scaling to twice it’s actual size, and I see it tween from it’s actual size tow twice it’s size, but instead of growing in both the XY directions at once, it first tweens the Y position then the X position.

    Here’s a test screen that eliminates everything except the tweening.

    Can anyone tell me what I’m missing.

    By the way I can move and fade the image with no problems, it’s just the scaling that doesn’t do what I expect.

    package info.garycaine.tilepuzzle.TweenAccessors;

    import com.badlogic.gdx.scenes.scene2d.ui.Image;

    import aurelienribon.tweenengine.TweenAccessor;

    public class ImageAccessor implements TweenAccessor {

    public static final int ALPHA = 1;
    public static final int SCALE = 2;
    public static final int POSITION_XY = 3;

    @Override
    public int getValues(Image target, int tweenType, float[] returnValues) {
    switch (tweenType) {
    case ALPHA:
    returnValues[0] = target.getColor().a;
    return 1;
    case SCALE:
    returnValues[0] = target.getScaleX();
    returnValues[1] = target.getScaleY();
    return 2;
    case POSITION_XY:
    returnValues[0] = target.getX();
    returnValues[1] = target.getY();
    return 2;
    default:
    return 0;
    }
    }

    @Override
    public void setValues(Image target, int tweenType, float[] newValues) {
    switch (tweenType) {
    case ALPHA:
    // would use setAlpha but there is no getAlpha
    target.setColor(1, 1, 1, newValues[0]);
    break;
    case SCALE:
    target.setScale((int) newValues[0], newValues[1]);
    break;

    case POSITION_XY:
    target.setPosition(newValues[0], newValues[1]);
    break;
    }

    }
    }

    package info.garycaine.tilepuzzle.Screens;

    import info.garycaine.tilepuzzle.TweenAccessors.ImageAccessor;
    import aurelienribon.tweenengine.Timeline;
    import aurelienribon.tweenengine.Tween;
    import aurelienribon.tweenengine.TweenEquations;
    import aurelienribon.tweenengine.TweenManager;

    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.Screen;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.scenes.scene2d.Stage;
    import com.badlogic.gdx.scenes.scene2d.ui.Image;
    import com.badlogic.gdx.utils.viewport.FitViewport;

    public class GameOptions implements Screen{

    private Stage stage;
    private TweenManager manager;
    private Texture texture;
    private Image image;

    private void setupTween() {
    Tween.registerAccessor(Image.class, new ImageAccessor());

    manager = new TweenManager();

    Timeline.createSequence()

    .push(Tween.to(image, ImageAccessor.SCALE, 3).target(1.0f,1.0f)
    .ease(TweenEquations.easeOutQuad)
    )

    /* scale to double size
    .push(Tween.to(image, ImageAccessor.SCALE, 3).target(2.0f,2.0f)
    .ease(TweenEquations.easeOutQuad)
    )
    */

    .start(manager);
    }

    @Override
    public void render(float delta) {
    manager.update(delta);
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    stage.act();
    stage.draw();

    }

    @Override
    public void resize(int width, int height) {
    stage.getViewport().update(width, height, true);

    }

    @Override
    public void show() {
    stage = new Stage(new FitViewport(480,800));
    texture = new Texture(“badlogic.jpg”);
    image = new Image(texture);
    image.setColor(1, 1, 1, 1);

    image.setScale(0.25f, 0.25f);
    image.setOrigin(image.getWidth()/2, image.getHeight()/2);
    image.setPosition(130, 200);
    stage.addActor(image);
    setupTween();

    }

    @Override
    public void hide() {
    // TODO Auto-generated method stub

    }

    @Override
    public void pause() {
    // TODO Auto-generated method stub

    }

    @Override
    public void resume() {
    // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
    // TODO Auto-generated method stub

    }

    }

  • I found the proble, I had a cast to an int in my tween accessor.

  • Thank you I had a friend who had their gold crown fall off. She was really concerned about what she should do. Just like the patient above, money is a big issue for her too. Thanks for your helpful post Dr.Craig, I just printed it out and will show her what you recommended.

  • Normally I do not learn article on blogs, but I would like to say that this write-up very pressured me to take a look at and do it! Your writing style has been surprised me. Thanks, quite nice post.

  • [...] Universal Tween Engine (UTE) è un’utile e semplice libreria che permette di applicare delle trasformazioni agli attributi di un oggetto attraverso l’interpolazione, che detto diversamente, è ciò che consente di realizzare facilmente delle animazioni. Si tratta di uno strumento davvero universale perché può essere impiegato ovunque, richiede solo un oggetto Java (Swing, OpenGL, ecc) con delle proprietà numeriche. Per iniziare fatevi un’idea con questa demo. [...]

  • Very good website you have here but I was curious if you knew of any user discussion forums that cover the same topics talked about in this article? I’d really like to be a part of online community where I can get feedback from other knowledgeable people that share the same interest. If you have any recommendations, please let me know. Cheers!

  • I intended to post you this little bit of remark in order to say thanks as before for the pleasing strategies you have featured on this website. This has been certainly incredibly open-handed with you giving without restraint all a lot of folks might have made available for an ebook in making some bucks for their own end, and in particular considering that you might well have done it if you ever considered necessary. These creative ideas likewise acted like the great way to be aware that other individuals have similar keenness just like my personal own to understand a whole lot more on the topic of this problem. I am certain there are many more enjoyable periods up front for individuals who looked over your blog.

  • We simply need to notify you that I am fresh to writing and thoroughly enjoyed your website. Quite possibly I am probably to bookmark your article post . You absolutely have excellent article posts. Be Grateful For it for expressing with us your blog page.

  • Prevent leaving behind large amounts associated with finance in any affiliate marketing or even event web page! Almost all sites employ a rigorous insurance plan on spamming along with for anyone who is at any time falsely accused (deservingly and also mistakenly) involving transmitting unrequested email messages, you

  • I only want to let you know that I am just beginner to blog sites and in reality loved you’re blog page. More than likely I am about to take note of your web site . You certainly have fabulous properly created posts. Cheers for revealing with us your online page

  • Hi there! Quick question that’s entirely off topic. Do you know how to make your site mobile friendly? My site looks weird when browsing from my iphone. I’m trying to find a theme or plugin that might be able to correct this problem. If you have any recommendations, please share. Many thanks!

  • Hello, i’m a bit new in Java, but i can understan many things, only that i can’t find the JavaDoc for the jars in the demo, could you please tell where they are?, this is the demo that i downloaded https://code.google.com/p/java-universal-tween-engine/downloads/detail?name=tween-engine-demo-6.3.0.zip&can=2&q=
    but there’s no javadoc

  • Hello, is there someone that can help me to make a SlideShow using Tween Engine?, i’m a bit new, and want to understand how to use these libraries, if someone can help i’ll appreciate it

  • Hi, can someone upload this project to maven, that I can use it with gradle?

  • Hi Aurelien,

    thanks for the great library!!!

    I have a question. I’ve downloaded the library to my “libs” folder. However, i’m using the latest libGDX version integrated with Gradle. How manage this library with my build.gradle file? I can’t see the files in my “eclipse files explorer”.

    Thank you very much.

  • I do believe all the ideas you’ve presented on your post. They are really convincing and will definitely work. Still, the posts are very short for newbies. Could you please prolong them a little from next time? Thanks for the post.

  • Hello to all, as I am really eager of reading this weblog’s
    post to be updated daily. It contains pleasant information.

  • Pls. can someone explain to me how to enable this library on my netbeans ?? i dont know how plssss..

  • Since the time Food Network started sreening professional chefs prodducing
    dishes of the best possible quality, housewives as wwell as businessmen are yearning to achieve the same outcome as that of chefs who are professional.

    If your knives are difficult to sharpen, you’ll end up spending more when you have them
    sharpened, and they may nneed sharpening more often. To avoid
    being fooled by a reworked knife, it’s important to understand that no old-time commercial knife factory ever used rag buffing wheels.

    My web page … chef’s choice electric knife sharpener australia

  • We stumbled over here by a different website and thought I
    should check things out. I like what I see so i am just following you.
    Loook forward to going over your web page repeatedly.

    Here is mmy homepage; Emergency Cash Kit Revealed

  • Lots of ways are there for making a stronger and perfect coffee of your taste.
    The 12-cup capacity glass and heat resistant carafe will be the perfect addition to this
    superb coffee brewer. No matter what you do, as long as you take care of at least one of the
    superheroes, the rivalry will be over and Uncle Roe will give you the agreed upon award.

    Look at my page: best coffee machine in the world

  • Very efficiently written post. It will be supportive to anybody who employess it, including myself. Keep up the good work – looking forward to more posts.

  • Thanks on your marvelous posting! I really enjoyed reading it, you’re a great author.I will make sure tto bookmark youhr
    blog and will eventually come back in the future. I want
    too encourage you continue your great work, have a
    nice morning!

    Feel free to srf to my site … Homemade Hydroponics Gardening

  • Hello,

    I apologize for my English is very bad.
    I wish I store an array type Spirte implemented by the sprits The ones sequential animation. I create the animation in a loop like this:

    for (int j = 0; j < Sprite.length; j++)
    {
    tweenManagers[j] = tweenManager;

    Sprite[j] = new Sprite(Texture);
    Sprite[j].setSize(SPRITE_WIDTH, SPRITE_HEIGHT);
    Sprite[j].setPosition(SCREEN_WIDTH + SPRITE_WIDTH, SCREEN_HEGHT – SPRITE_HEIGHT / 2);

    Timeline.createSequence()
    .push(Tween.to(Sprite[j], SpriteTween.POS_XY, 1000.0f)
    .target(25f + spriteSpace * j, GGD.SCREEN_HEGHT / 2)
    .ease(TweenEquations.easeInOutElastic)
    .repeat(0, 0))
    .pushPause(1000)
    .start(tweenManagers[j]);

    startTime = TimeUtils.millis();
    }

    The problem is that the animation of all elements of the array are run simultaneously. I want to go into the first element of the array is the top side of the screen then follow the second element of the array, and so on.

  • I like the heslpful information you provide for your articles.
    I wiol bookmark your blog and take a look at oce more here frequently.I’m quite sure I will be told a lott of new stuff rught here!

    Good luck for the following!

    My page; ice cream maker best recipes

  • This article gives the light in which we can observe the reality. It ias very nice and gives in depth information. Thank you for this wonderful article

  • “Wow, great post.Much thanks again. Fantastic.”

  • One other issue is when you are in a scenario where you don’t have a cosigner then you may actually want to try to exhaust all of your educational funding options. You can get many funds and other scholarships and grants that will give you finances to support with education expenses. Thanks alot : ) for the post.

  • Very neat blog article.Really thank you! Keep writing.

  • I like the valuable information you provide in your articles. I will bookmark your weblog and check once more right here frequently. I am relatively sure I’ll be told many new stuff proper right here! Good luck for the next!

  • Really enjoyed this post.Much thanks again. Awesome.

  • Thanks for the blog.Much thanks again. Want more.

  • Nice post . carry on the excellent work And like most people, maybe you lack the expertise to eradicate said virus, making computer virus removal about as big a reach as, say, dealing with your transmission or tailoring a suit.

  • You have brought up a very great details , thanks for the post.

  • “Appreciate you sharing, great blog.Really looking forward to read more. Fantastic.”

  • What academy accomplish you go to? Shy Lolita Lovely big Clit. Wet wet wet fucking lovely. She cums hence pale yellow. I would adore to lick it up or achieve her cum on my face and taste her cream mmmm

  • “Great, thanks for sharing this article post.Really thank you! Really Great.”

  • Thanks again for the blog. Keep writing.

  • Hi, first of all congratulations for the wonderful library :-)

    I’ve write a simple code for a splash screen with a tween. I’ve write the code and I’ve add the libraries for tween engine but when I debug the game, it crash:
    Exception NoClassDefFoundError
    GLSurfaceView$GLThread.run() line:1252
    The source attachment does not contain the source for the file GLSurfaceView.class.

    How can I solve it?

    IDE:
    Eclipse

    LIBRARIES:
    LibGDX 1.4.1
    Tween Engine 6.3.3
    Android API (I run/debug my game from my phone that have API 15 [Android 4.0.3])

    Thank you :-)

Got anything to say? Go ahead and leave a comment!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>