Attention: you're visiting an archived version of this post on my old website. Click here to view this same post on my new website.

On user-triggered and user-controlled interface animation

Working on the development of Flash interfaces, there’s a very important aspect of screen element animation that often comes up on advanced actionscript discussions. It’s an easy question, but one with no easy way to explain, much less respond - when to use tweening animation controlled by tweening engines or classes, and when to use some other custom approach?

I have to admit my academic vocabulary isn’t exactly the best when it comes to this issue; I don’t know if such a thing even exists. However, here, I’ll try to show two different ways of animating screen elements; and since it’s at the heart of this matter, and also because it allows me to feature a couple of new examples with source, I’ll do so by using Tweener, my own tweening extension. This discussion is not exclusive of it, though, as any other tweening extension available now works the same way and falls into the same usage patterns.

First of all, when it comes down to most animation development under the Flash platform, there are two kinds of animation you’ll see: user triggered animation, and user controlled animation.

An user triggered animation is what happens when, say, you click a button and something happens. Or when you’re playing a game, and you fire some kind of bullet; the bullet itself is just traveling at a certain speed, going in a certain direction. It is not controlled by the user anymore, even if the user has triggered its action (or its animation).

All the animation we create with “tweening” code on Flash are, by definition, user triggered animations. We, as developers, fire the bullet that will travel from one point to another on a set amount of time; maybe the user has limited control of that animation, maybe he can cancel it, pause it, remove it; but he can’t control it anymore. As such, the tweening is the act of going from one value to the other on this predefined amount of time.

Below is a classic example of user-triggered animation (download fully commented source for Flash 8 here):

{}

What we see is an interface with a number of icons and a few buttons. Clicking on the buttons, the user can control which is the icon currently displayed on the middle of the list - but he exercises this control by triggering events, such as the sliding animation. He has limited control over what’s going on - for example, in the middle of a sliding he can press the button again and override that previous slide with a new slide - but he can’t do much more than that. He can’t stop halfway through a sliding animation; he can call the shots, but he doesn’t have micro-control over what’s going on.

(This example also shows the new BlurFilter tweening capability of Tweener, by the way. Other filter tweenings will follow shortly)

On the other side of the interface animation spectrum is what I call user controlled animation. On this kind of animation, the user has direct control over what’s going on, and how - he can play with the interface and make it assume whichever state he so desires. Thing of a spaceship game - you’re in direct control of the spaceship’s movement, so you’re not triggering animations, but instead directly controlling the position of the spaceship when you go up and down.

Again, here’s an example (download fully commented source for Flash 8 here):

{}

On this Mac OS X dock simulation, the user doesn’t have any button to click; rather, he approaches the mouse to the list of icons and the icons start responding to his movements. The important thing, here, is that the menu is redrawn whenever the user moves the mouse, assuming a new configuration; therefore, the user is directly controlling the action, instead of triggering specific actions.

With that said, the level of input the user has determines the approach the developer should take when implementing the interface. Key point: the second approach (the dock above) doesn’t use any tweening to control the main icon animation. When moving the mouse left and right, the user is directly controlling the state of the menu, and the task of the actionscript code is then to translate that (the current horizontal mouse position) into respective position of the icons and their scales, and not animate things from one point to the other; the animation comes naturally, because the user input is organic, fluid.

It is very often that people - specially beginners - assume that, if something is moving on screen, it must have been created by tweening values, by using an extension such as Tweener, Adobe’s own Tween class, or the many other equivalents. However, this is hardly the case. It’s important to understand that, when the input is constant (as in a mouse moving left and right), when the user is in direct control of the action, tweening extensions with a fixed target value and a fixed amount of time to reach that target are not the solution to look for. Even with tweening extensions that let you change any of these parameters during execution, you’ll be dealing with broken animation patterns; the solution, instead, is to embrace the user input and act as a wrapper to it, be via direct translation of the user movement (as above) or by adopting certain easing or inertia algorithms that go in a different path than the one tweening extensions do.

Maybe a better way to describe user-triggered and user-controlled animation are digital and analog, respectively; on the digital side, you just control the meta-information that leads to certain transformation, translating single pieces of information (like a click) to some predefined animation; on the analog side, the user has direct control so, by definition, the control he sees on the screen is analogous to the input he’s feeding the interface. There is no tweening involved, just translating.

That is not to say tweening should be totally forgotten, though. On the above example, the code uses Tweener on two very important points: first, when the dock is activated or deactivated, to provide a smooth entrance to the dock scaling (on the zoomedAmmount variable, 0 means at rest, 1 means maximum focus on the dock):

this.activateDock = function() {
	(...)
	Tweener.addTween(this, {zoomedAmmount:1, time:0.6, transition:"easeoutquint"});
	(...)
};

And second (and most surprisingly to some people I’m sure), when determining the scale of each icon based on is proximity to the mouse cursor, one of the animation equations is used to provide a smooth scaling curve over the dock icons, avoiding an unnatural, linear scaling:

// Close enough to the cursor; "easeInOutQuad" is also good
itemScales[i] = Equations.easeInOutSine(1-Math.abs(distanceFraction), scaleSmall, scaleBig - scaleSmall, 1);

Finally, the reason why I’ve created this example based on the Mac OS X dock (or something close to it) is because people usually look at the visual aspect of interface elements when judging what has to be done, but forget about the way it’s supposed to behave. Even if “an icon increasing in size when it is focused” sounds like the Mac OS X dock, it’s not always the case, as the first example above uses this very same concept but is very different from the OS X dock in the end.

My main point is that the implementations of both approaches - animations that are user-controlled, or user-triggered - are extremely different from one another, and on the case of animation that’s directly controlled by the user, you hardly ever need to use tweening extensions. There are problems (and solutions) that lie in the middle of these two control levels, I’m quite sure; but remember that, just because there’s something moving on the screen, doesn’t meant it has - or even that it can - be a tweening.

Posted on 4/Apr/2007 at 12:23 pm | Comments (0) | Trackbacks (0) | Categories: Actionscript, Design, Easing, Flash, Interface, Sources, Tweener

Comments (5)

Very good post, Zeh. I think I’ll share this with my students. Just made the move from MCTween to Tweener. It’s great, can’t wait for the rest of the filters to make it over to the new engine.

Posted by Chad on 5/Apr/2007 at 6:09 am

I was always looking for this interactivity in Flash
Man you are brilliant!!

Thank you so much for sharing!

Tamer

Posted by Tamer on 9/Apr/2007 at 3:18 am

Great post! It took me a while to figure out exactly when to use the appropriate method. You’ve broken it down very well.

Posted by Mike on 30/Apr/2007 at 5:17 am

Excellent work on the dock! Yours is probably the best example of bringing this excellent and highly intuitive functionality of the mac into flash. I’ve seen many an attempt at this, and your work trumps them all. I especially like the code structure and organization! Clearly, you come from a solid software background. Very good to see this in a flash dev.

Posted by Alex on 21/Dec/2007 at 11:28 am

This file is awesome :) Just wondered how i can bring the icons back to there original position when i move the mouse out of the movie (down).
they get stuck to there last position… (sorry for my denglisch)

Posted by Kalli2000 on 4/Apr/2008 at 2:06 am