Gotcha – transform.matrix and scaleX/Y
I came across this gotcha for the first time today. Praise-be to ASUnit, without which this could have been extremely difficult to unearth:
// given two sprites called "a" and "b"... a.transform.matrix = new Matrix(-.5, 0, 0, -.5, a.x, a.y); b.scaleX = b.scaleY = -.5; trace(a.scaleX, a.scaleY, b.scaleX, b.scaleY); // outputs: 0.5, 0.5, -0.5, -0.5
Both clips have been scaled by -0.5, but because the transform was used to produce the scale for a, the scaleX/Y variables do not reflect the object’s true scale.
Now, just to confuse yourself, add a third sprite to the stage:
// given another sprite called "c"... c.transform.matrix = new Matrix(-.5, 0, 0, -.5, c.x, c.y); c.scaleX = c.scaleY = -.5;
Curiouser and curiouser! This needed a more complete experimentation…
The source for this experiment can be found here: scaleAndTransform. The buttons call the following methods:
function onGo(event:Event):void
{
a.transform.matrix = new Matrix(-.5, 0, 0, -.5, a.x, a.y);
b.scaleX = b.scaleY = -.5;
c.transform.matrix = new Matrix(-.5, 0, 0, -.5, c.x, c.y);
c.scaleX = c.scaleY = -.5;
}
function onResetScale(event:Event):void
{
a.scaleX = a.scaleY = 1;
b.scaleX = b.scaleY = 1;
c.scaleX = c.scaleY = 1;
}
function onResetTransform(event:Event):void
{
a.transform.matrix = new Matrix(1, 0, 0, 1, a.x, a.y);
b.transform.matrix = new Matrix(1, 0, 0, 1, b.x, b.y);
c.transform.matrix = new Matrix(1, 0, 0, 1, c.x, c.y);
}
What Is Going On?
If you apply a transformation matrix then a scale, the magnitude of the scale is applied, but the direction is determined by the product of the transformation and the scalar… which is to say that:
a.realScaleX = (a.transform.matrix.a * a.scaleX > 0 ? 1 : -1) * a.scaleX;
If however you apply a scale then a transformation, the scale is defined by the transformation only!
a.realScaleX = a.transform.matrix.a;
Bug?
Does this qualify as a bug? I haven’t thought about this for long enough. The conditions in which a transformation matrix rotates and skews the MovieClip confuse me; how would I define scaleX and scaleY in that scenario? I need to give this some thought; perhaps you the community can give me some help! I am reluctant to call anything a bug immediately now, after my experience with my The Problem With Vector.<T> post, where I was just plain wrong!
A similar bug exists in Adobe JIRA: UIComponent.scaleX, scaleY differ from transform.matrix.a,d. You’ll need an account to look at this – it’s free, and once you’ve got it you can pester Adobe with your bugs too.
-
http://twitter.com/robpenner robpenner
-
http://alecmce.com alecmce
-
http://pulse.yahoo.com/_PTYBDR6MTFEVR2YFI2WJJ4SPH4 Niko Nami
