I often talk about the important role visualization plays in my work. I personally don’t really understand things until I can see them. One example of this that I showed at FitC this year was the SparkTable tool I use to visualize and compare easing equations. It’s very simple, but I’ve found it very useful when trying to choose between two similar eases, such as a quintic versus exponential ease. It’s also very handy when developing custom easing equations.
Simply queue up a bunch of easing equations to test, then sit back and watch the results.
import fl.motion.easing.*; queue(Sine.easeOut,0x660000); queue(Quadratic.easeOut,0x990000); queue(Cubic.easeOut,0xCC0000); |
Here’s what it looks like in action (scaled to 50% to fit on this page).
I like that you can either view the graph to see a static representation of the output values, or you can simply focus on the white box at top or bottom to see what it looks like in motion.
It also demonstrates an interesting rendering bug in the Flash Player. Watch the white line carefully where it joins the top box while it animates, it will appear to separate with the box one frame ahead of the line (this is much easier to see if you download SparkTable and run it at full size). The line and the boxes are all a single clip though, animating together – something is going screwy with the rendering engine. Watch carefully as the first tween runs, and you will see the point of separation move down the line with the graph. Interesting. Perhaps related to multi-core support? Let me know if you don’t see this issue, and what platform / Flash player version / CPU you are using.
You can download the SparkTable fla here.
This is what I have been dreaming for! Nice work!
The separation looks like tearing caused by lack of vertical sync for the rendering engine. While Flash uses hardware acceleration, I do know it had a problem with sprite tearing in previous versions.
I only saw the issue intermittently on my machine with your demo, and it was barely noticeable at 60Hz on my monitor.
Platform:
Windows XP SP2, 9,0,124,0 (debug), P4 3.2 GHz (with HT enabled, so pseudo-multicore), 60 Hz screen refresh (changing to 70 Hz actually made the issue worse, and actually noticeable)
Syncing the player framerate (at least when it renders) with the vertical blanking of the monitor would correct this issue entirely, but may introduce playback hiccups if introduced at the player level, which is likely why Adobe has not implemented it yet.
I do not see the bug you describe. When I put the movie at a lower framerate it is still not visible. This might be caused because I am using a fast computer.
In some of our own projects we noticed that animations were not good enough using an ENTER_FRAME handler. This is why we (as it is done in the Flex framework) most of time use a Timer. This timer fires every 10 miliseconds. The managing class has an event listener to this timer as well with a low priority. This listener will call the .updateAfterEvent method of the event.
Back in the AS2 days, we used a similar technique where we would call the updateAfterEvent method at the end of the onEnterFrame method. This would help smooth up the animation.
I am not sure if this would help to solve the effect you are seeing, you might give it a try though.
I would not recommend the updateAfterEvent method for applications that do alot of other stuff as it eats a bit more resources. It is also good to note that most existing tween engines do not use it as it will bring down performance in benchmark tests.
Greetz Erik
I can’t really see any issue. I will, on occasion, have it stall (where I can see it looks like it’s jumping frames) for a split second, but that’s about it.
I’m running a Xeon 3ghz, flash 9,0,124,0, with Windows XP pro.
“In some of our own projects we noticed that animations were not good enough using an ENTER_FRAME handler. This is why we (as it is done in the Flex framework) most of time use a Timer. This timer fires every 10 miliseconds. The managing class has an event listener to this timer as well with a low priority. This listener will call the .updateAfterEvent method of the event.”
Correct me if I’m wrong (which has been known to happen pretty often), but doesn’t the Timer class use ENTER_FRAME anyways? The way I understood it is that the timer class just “approximates” the time and can be slightly slower depending on both the the complexity of the code you’re running and the frequency that you run it. If you up your frame rate, your timer class would be more accurate, and a lower frame rate could reduce accuracy.
As far as I know, the Timer uses a signal generator (I don’t know the exact word) provided by the environment. This signal provider provides points where the Flash player will trigger the rendering of the frame. More info here:
http://www.kaourantin.net/2006/05/frame-rates-in-flash-player.html
The result with the Timer is more smooth than the result with ENTER_FRAME. I am not completely sure why this is. I have 2 guesses as to why this is:
1. The updateAfterEvent method causes some sort of pre-render, making sure everything is at the correct place at time of ENTER_FRAME.
2. (this one seems a bit more likely) The updateAfterEvent method actually starts to render the screen. This causes the effect that your Flash movie will (while you call the updateAfterEvent method) operate at maximum framerate.
After I wrote the above bit I did some tests. I was able to get a smooth transition with a framerate of 4.
>but doesn’t the Timer class use ENTER_FRAME anyways?
Apparently it does not. They both get a call from the same signal provider and then fire their own events as close as they can to the given time (or framerate). This would mean that a maximum framerate would have the same speed as a Timer at maximum speed. Tests seem to support this theory.
Greetz Erik
On the subject of tweening, does anyone have any good ideas how to solve the problem of getting consistent easing for tweens where the length of the tween is unknown? For example, tweening a sprite over a distance that isn’t predetermined and making it ease in to a maximum velocity, then ease out at the other end.
My current idea involves easing the object in in the normal manner, using an enter frame for the constant velocity part, then easing out. The distance covered during the ease out would need to be calculated in order to start it at the right point. Situations where the distance is not long enough for the maximum velocity to be reached would also need to be accounted for.
Any ideas people?
It is really a Nice tutorial…. Respected Sir can know layer name on which mask is present, By loading a Masked swf in another swf & finding Which layer is mask or not…….AnD is there is any other method for OnEnterFrame…