A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.
I'm wondering if anybody has any experience programming user interfaces which has some animated effects in it.
For me, an animation is something like transition between two PowerPoint slides, or progressive highlighting of a scrollbar (think about the new Vista controls).
What I'm interested in is that what programming patters these follows, especially if there is more than one animation at a given moment.
Maybe a background thread to calculate a given "frame" and then the UI thread draws those? How about multiple animation? Obviusly you cannot create one thread for one animation.
To phrase it in a different way, Macromedia Flash is something that is built on this. Millions of small object animate. Is it a simple background thread to calculate each frame?
What do you think?
Sunday, November 18, 2007
I have no experience with those APIs. For simple fading, I'd look for an API which:
a) lets you control the transparency
b) lets you change the transparency from 0% to 100% (and vice versa) over a duration that's specified by one of the API parameters.
I'd hope that an animated fade can be controlled by the graphics card (or failing that by the kernel-resident gdi.dll), because then the fading may be smoother than if it's controlled by the application program, whose threads are prone to be interrupted.
If there were no such API, I'd beware of touching the screen with a background thread: Windows generally like to be updated by the thread which created them; so perhaps I'd look at updating them from a WM_TIMER message.
> perhaps I'd look at updating them from a WM_TIMER message
If the amound of time it takes to do the update is longer than the timer tick period, and/or for other reasons, you may end up 'missing' some of the ticks: so in the tick handler, get the real-time time of day to determine the actual time ellapsed since the last tick, and be willing to do several ticks-worth of alteration in one shot.
You can have a private list of all the things that are being animated: no need to have a separate tick-event-handler (or background thread) for each thing.
You structure each object's update function as a state machine. Each time round, it performs one update's-worth of updating, then returns.
The "trick" is to get around the fact that you're trying to have a function whose context survives its return. There'll almost certainly be some state involved in any animation, whether it's simply a position delta to be added for each frame, or something more complicated like a position delta, the position the object is to move to, and some kind of speed multiplier type affair to get a nice acceleration/deceleration effect. So you can't have these as locals, because each object's update function has to return so that the next object can be updated, but will instead have to put them away in some object, probably heap-allocated, that will live on after each invocation of the update function.
That's one side of the state management; the other is more insidious, and rears its head if your object has multiple "modes" it can be running in. For example, our object above might have to flash a couple of times, fade itself down, THEN move, then fade itself back up and flash a couple more times before becoming inert. In this case, you "simply" need to structure the entire thing as a state machine, store in your state object the current state it's in, then inside the update function switch on the state to work out what to do this time round (and maybe change state whilst it's at it).
This latter aspect is usually where any complexity comes in, because you're taking what would ideally be straight-through code, relying on the compiler to manage all the local variables for you, and you're twisting it inside-out by hand. And any time you do by hand what the computer could do for you, you'll get it wrong at least once, and it'll be annoying to fix -- but there's not much to say about this, except that you'll have to deal with it somehow.
(A good solution to this kind of thing is to implement the UI animation etc. in some kind of extension language that supports the notion of yielding control whilst retaining the current execution state. But this is more food for thought than a recommendation, because if you've never done this sort of thing before it's more illuminating to try doing it by hand first. Then, rather than simply taking my conclusions, you can come up with your own.)
Sunday, November 18, 2007
Oh -- and in case it wasn't clear from my "explanation", you don't need to use multithreading for any of this. Indeed, I myself would consider it a bad idea, but tastes differ and you may consider it just the ticket.
Sunday, November 18, 2007
> This latter aspect is usually where any complexity comes in, because you're taking what would ideally be straight-through code, relying on the compiler to manage all the local variables for you, and you're twisting it inside-out by hand.
The C# "yield return" statement makes this kind of coding a lot easier.
There are some pretty simple animation frameworks that let you declare a state for each object and the engine takes care of moving them. The Commodore 64 had a simple and effective sprite engine that performed the updates. The most critical issue was being able to perform a full update at a rate of 12 fps or better.
I also agree with Tom on threads ... there shouldn't be separate threads for each object, but there should be separate rendering and user input threads.
If you can use the technology, you should consider WPF (.NET 3.0).
It has build-in support for animations and allows you to do them declarively (in xaml) using storyboards.
Monday, November 19, 2007
I recently wrote up some thoughts on what it takes to optimise animations in a Web browser. While this is a more limited environment than Windows and a much more limited environment than CoreAnimation on OS X, it gives you a sense of what goes into making animations perform ideally.
The url is: http://nerd.metrocat.org/2007/11/spooky-code-or-how-to-make-animations-run-smoother
From an API standpoint, you have simple animation chunks: set opacity, change text, move, resize, etc. These get composited into larger animations either serially or in parallel.
Fortunately, most applications don't really need very complicated animations. A resize here and a fade there is usually sufficient.
Tuesday, November 20, 2007
This topic is archived. No further replies will be accepted.Other recent topics
Powered by FogBugz