Lqd's Journal

Icon

It's actually pronounced liquid!

Animation speed and dynamic motion blur in Swing with JavaFX’s Scenario

Introduction

In the last article about triggers, i mentioned a use case which was very interesting to me, and would allow handling the motion blur automatically in an animation. This pretty simple addition, as you’ll see, makes a big difference in the dynamism and realism of an animation. Let’s see how to do that. And of course, there’s a hopefully cool demo+source that comes with it.

Speed (instantaneous speed) is easy to calculate: it’s a delta between two values, divided by the delta of time it took to get from the first to the second value. (We often think of the values in space, for motion, but this formula ca be applied to any dimension, since it relates to the speed of any change). Cue timing events, and all you have to do is find the difference between the last value of the property you’re animating and the current one, and the difference between the times at which the events occured.

float delta = Math.abs (currentValue - previousValue);
long deltaTime = elapsedTime - previousElapsedTime;
        
float speed = delta  / deltaTime; // speed per ms

I said it was going to be easy! Plus i’ve built a speedometer class to help you with statistics, filtering events, and calculating the speed.

Once you have the speed, you need to find a way to use it. What i wanted was a relationship between that speed, and the motion blur itself: the faster the animation, the bigger the motion blur radius.

We’ll tackle the specific speed trigger next time (because i thought about it a little more, and the concept is pretty powerful. Triggers shouldn’t be in an animation library but directly in the core libraries or in a ui tk, at the very least, so next time we’ll see what i came up with), today we’ll use a component of that equation to make a fully dynamic motion blur: we’ll use the delta values as a basis for the blur radius.

Demo

The demo looks like originally like this.

The basic demo

Not much going on. There’s a white surface on which the animations take place. It comes with 3 presets. Each preset launches an animation with a different duration and spline interpolator (which changes the speed for each one), the text goes from top to bottom. You can also click the surface, and the text will smoothly move there, motion blurred and all (look at the code to know how to calculate an angle involving a mouse click).

You’d be impressed by how fast a little animation goes; in the demo, some of them go from 0.3 to 29k+ pixels per second. Obviously with that much of a gap, it’s almost impossible to get to a good looking animation by hand coding and eye balling. I had to build a little editor to make the presets i just talked about. It’s activated by clicking the “animation editor” button, no kidding, and looks like this.

emotionblur-editor

The editor obviously allows you to change everything in the animation, from the text, its color (using jeremy wood’s colorpicker), font (using connectica’s font picker), the motion blur settings (used here by the play button, or when clicking on the white surface), to modifying the spline interpolator (using a slightly modified version of the one romain guy did in the timingframework, to adapt it to scenario and other things) by dragging the round anchors or using the template selector, and also allows you to see the actual graph representing the animation speed, if the animation were to be run with the current settings.

Try the demo, i think it’s cute, note however that hardware acceleration is going to be a must-have here. There’s really no way you can animate a 60px radius blur effect smoothly and easily without it

webstart

Download the source (zipped eclipse project) here. The stuff i wrote is under BSD as always.

PS: The demo is using the scenario library that powers JavaFX. I’ve used the recently released version 1.2, which should work on all platforms, but i’ve only tested it under windows and linux so your mileage may vary. The demo’s name was in direct relation to the mythical 4th preset (which you can see in the screenshots but only try if you download the code), blurring emotions as well as pixels on screen, you can think of that as poetry if you will.

My own emotions were actually blurred too when updating to v1.2, since a lot of things i relied upon in the scenario framework since its public release 18 or so months ago, were either moved to fx script or removed altogether. I’m slowly bringing them back to life, piece by piece, i’ll make a post about using scenario 1.2 in java in the near future, and maybe win the 500$ sun is offering for their latest blog challenge in the process hehehe (:

Let me know what you think here or on twitter.
See ya.

Swing event triggers for Trident animations

Trigger happy ?

Starting and stopping animations is usually related to events occuring somewhere in your ui. Writing those event listeners can be verbose and tedious at times. Chet Haase (one of the great, we miss you buddy) solved this problem in his TimingFramework animation library by providing a small core of extensible classes dealing with events: triggers (example here).

They allow you to say: start this timeline when the user interacts with this button, or start this timeline when the mouse enters that component and reverses it when it exits, and so on.

While testing Kirill’s Trident library, i thought this feature could be nice to have, so i ported Chet’s trigger code over to support it.

Meet the cast

Triggers are useful for one-shot events, like action events, but some events have an “opposite” event (pressing and releasing the mouse, entering and leaving a component, etc). The good thing is you can create an “autoreverse” trigger that will play the timeline backwards when this opposite event occurs: the values will smoothly be animated back to their original value. This is great for hover animations for instance.

Almost all of the original triggers have been ported except for the ones that didn’t make sense in this new context (TF uses triggers on animations to group them, in sequence or in parallel – eg start this animation when this one stops – and Trident supports that use case with timeline scenarios, so i didn’t feel they were needed here, feel free to comment on those)

Specifically, the supported event triggers are:

  • Mouse triggers: enter, exit, press, release, click
  • Action triggers: supporting actionPerformed
  • Focus triggers: gain, loss

The How

In the zip file linked at the bottom, you’ll find the simplest Trident demo modified to show how you’d use triggers. With that, the javadoc and the simple API, everything should be self explanatory.

Here is the one liner you just need to write to have a hover animation – while the mouse is over a button.

MouseTrigger.addTrigger (button, timeline,
    MouseTriggerEvent.ENTER, true);

And here’s the one starting a timeline when the button is pushed.

ActionTrigger.addTrigger (button, timeline);

Pretty simple. Thanks Chet ! (:

In the future, it might be possible to have triggers apply automatically to the object you’re animating. I’m not sure you can get that object back from the timeline right now, but it could be interesting to have for this very reason, and also to have callbacks that know about the main object without needing to give it to them (saves some code for repaints for instance). We’ll see with Kirill about that.

Extensibility, and porting existing triggers

Triggers are definitely an interesting concept, and the better thing is they can be extended easily. Maybe one could need triggers for other events. Feel free to ask, or do it yourselves (and maybe we’ll backport them to TF too, then).

For instance triggering animations on mouse wheel or drag and drop events, property changes, or maybe virtual events resulting from other changes. Those could be really useful for saying: start this animation when the mouse dragged this widget more than 10 pixels to the left, or my favorite (kinda hard to do at the moment, but i’m working on it) fade in and grow the radius of this motion blur when this widget is moving faster than x pixels/second and reverse that when it slows down (Those are the kind of features you usually only see in SFX tools like After Effects and the like, and i’d love to have that kind of power in Java too).

If you have an existing TF trigger, or if you find one you like on the intertubes and would want to use it with Trident, about the only thing you’ll need to do is replace the references to TF’s Animator to Trident’s Timeline, and that should be it since i’ve kept the API exactly the same (except renaming the focus constants, a subjective change, i thought FocusTriggerEvent.GAINED was more natural than FocusTriggerEvent.IN, could be better as FocusTriggerEvent.GAIN since the mouse’s are MouseTriggerEvent.ENTER and not ENTERED for instance, definitely something we can talk about). Let me know if you run into problems.

Creating one should be really easy too, just looking at the code for the core ones should convince you of that.

Okay, i’m sold, sir, where do i sign ?

Binaries here, source here (eclipse project, also includes the latest available trident jar as of right now, rev 42), sign here, credit card there, thanks mam and have a nice day.

As you probably know if you’ve read my previous posts, i’m more involved with Scenario at the moment (the über cool java thingy hidden under the arguably less cool javafx script thingy in the javafx runtime) and its animation support (based on evolving TF). However, I strongly encourage you to look at Trident, and its demos (+ Amber and Onyx) if you plan on adding animations to your java/swing apps (which you should, for basic usability reasons – hello, transitions! – at the very least).

Both Trident and TF are great animation libraries, the advantages Trident has, even though it’s probably less mature, is that the project is alive (TF’s state is not really clear, dormant, dead, spending spring break in Cancun, i don’t know), has some features TF is missing, and that it’s made by Kirill. TF’s are that it’s older and for that, probably used more, it has features Trident is missing, is more documented (the most recent doc is in a book, printed on real paper ! but you have to pay for it) and is made by Chet. Scenario’s animation support is good but has problems, mainly the license and the fact that it’s dead for the open source version, and the license and Oracle in the picture for the proprietary version (+ it’s proprietary i just said it).

So, triggers huh ? Hope you like it, see you soon (with something totally unrelated), or sooner than that on twitter.

xoxoxo
Rémy