Jump to content
GreenSock

da2020

accessing high precision x/y values for the tweened object?

Recommended Posts

This is beyond the scope of normal tween use cases (yeah, I know, what a surprise), but I have a need to precisely measure the straight-line distance between two points (ie, two timeline "time" values)  along a bezier tween (which is nested in a timeline). I'm doing it now by setting timeline's "time" to point A, and then to point B, and recording the x y properties of the invisible tween target object at each point -- then it's just a matter of doing arctan2 on the diff y and diff x -- works great generally, but....

This distance calculation's accuracy is limited by the .05 pixel "twip" resolution (hence, round off error) that any flash display object's x and y properties are subject to.  This resolution is fine for most purposes, but, in this case, that distance value is being used to dynamically alter the length (via scaling) of objects as they move along the bezier path ---- the .05 round-off error on these two points results in small, but noticeable (and undesired) fluctuations in the length of the objects moving along the path where sharp turns don't even exist (due to this random round off variation at various positions). Using a threshold to be less sensitive to this variation is one solution (but this has other issues).  

Anyway, I'm pretty sure that I could eliminate this problem if I was using the high precision Number type values that I suspect the tween uses internally to drive the tweened object's position.

So, wondering if there is, without much fuss, a recommendation as to how these values could be accessed. Or, I'm certainly also open to a better way with the regular API, if there is one.

 

For anyone that might be wondering, the purpose of all this is to make a series of graphical shapes that are following a bezier path (where "flow" is being simulated), such that, when these objects encounter a tight turning radius or sharp "point" in that path, they gracefully "shrink" (length-wise)  in order to better track the path at that sharp turn point,  and then grow back to full length as they come out of the sharp turn..  Essentially, I'm populating a bezier with evenly spaced graphics that "flow" down a path, like the 2D path plugins provide built-in support for when using circles, ellipses, and rectangles -- but since the bezier plugin does not support such populating and animation, I'm rolling my own solution based on the bezier plugin. 

As I said, this scheme already works fine except for the issue above, so there's really no need to worry about why I'm doing this if you don't follow my "purpose" explanation... I'm just looking for a suggestion on getting to those high precision x/y  tween positioning values.

 

Thanks,

 

Doug

Link to comment
Share on other sites

Instead of tweening DisplayObjects, display a generic object with numeric properties (or your own custom class). Think of it as a proxy of sorts. For example, let's say your "real" target is a DisplayObject named "mc":

var obj:Object = {x:mc.x, y:mc.y};
TweenLite.to(obj, 2, {bezier:[{x:100, y:200},{x:500, y:0}],  onUpdate:applyValues});
function applyValues():void {
    trace("x: "+obj.x+", y: "+obj.y);
    mc.x = obj.x;
    mc.y = obj.y;
}

The whole point here is to work around the fact that Flash forces DisplayObject x/y values to round (after they're set). GSAP is actually setting them very precisely, but then Flash is doing the rounding afterwards. Like:

mc.x = 20.123456789;
trace(mc.x); //"20.1"

But if you tween a different type of object, you'll get the precise values. 

  • Like 1
Link to comment
Share on other sites

Thanks Jack -- very simple and effective solution, where the flexibility of the tween exceeded the flexibility of my brain :)   I had a blindspot in my thinking that the bezier's tweening of "x" and "y" properties needed to be the standard x and y coordinate properties of display objects.

 

Turns out I'm already using a proxy tween object, and tracking via onUpdate as above, for registration point offset/centering purposes, but both those objects need to be display objects since the proxy has to serve as a container for the target. Nonetheless, I should be able to just make use of the generic object as you suggest as a proxy for the proxy. 

Link to comment
Share on other sites

Update - interesting observation/discovery:

I used the generic object as tween target object approach suggested to get the high precision values for x and y, to support the point to point distance calculations in this bezier "flow" animation.

It did work fine and yielded the high precision values expected from a non-display object, and it did marginally improve some of the "dithering" I had before on the scaling being performed. 

 

But, the most noticeable scaling fluctuations were still present in places where this should not have been occuring.  In certain portions of the path, the animated graphic objects would gracefully shrink and then grow (technically they were slightly slowing down and speeding up, but my scaling was masking that visually). So rather than the shrinking only occurring in tight turns/sharp corners of the path as intended, it was also occurring in shallow parts of the curve where it should not, specifically in areas where there was a transition from a straight path into a shallow curve (before reaching the most curvy zone where the anchor points were located). 

Since I'm using timeline.time() to set the evenly spaced animated graphic positions along the path on each frame, it was as if there were some slight non-linearities in the time vs distance-down-path relationship. Which then made the thought of the bezier's "time resolution" pop in my head.  I had set this value to 10 long ago, thinking that was a "very high" value that would assure near-perfect time/speed linearity throughout the bezier paths (and it appeared to when I was just bezier-tweening single objects down the path -- so have not concerned myself with it since).  But, with these closely, and precisely space objects used in this "flow" animation, the value of 10 turned out to be not high enough. Long story short, I needed to kick it up to the 25-30 range for these fluctuations to no longer be noticeable --- now it appears rock solid, and the scaling only occurs where it's supposed to (which actually means the time-distance linearity is now close enough to "perfect".

 

I would never have guessed that values above 10 for time-resolution would have ever been necessary, but they were in this case.  It was also fascinating (to me) to see how predictable/repeatable the locations of the non-linear "distortion zones" were with the value at 10 -- always in areas where there was a transition from straight to slight curve or vice versa, but not really noticeable anywhere else...   Anyway, I think the problem is solved with these changes, and for anyone looking to use timeline time settings to position a series of closely spaced graphics in an animation, it's good to know that time-resolution can have noticeable influence at values well above 10. I was concerned that the higher values (30) that I ended up needing to use would increase the processing time/cpu load, but I have not noticed a significant difference in cpu load so far (most of the load is from vector engine work involved in moving the many pre-drawn objects along the path, with smoothing to avoid a horrible look,  and transforms for rotation (path orientation)  and scaling).

 

- Doug

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×