Annoying AS3 Bug with rotation and height/width

I found a very problematic and reproducible bug with ActionScript 3 and simple display object transformations (width, height, rotation), and thought I should document it to save other developers some debugging time.

Put a 200x200px square clip on stage named foo. Add the following code.

foo.height = 100;
foo.rotation = 90;
trace(foo.height);

As expected, this traces 200. It scales the clip vertically, then rotates it, so that it is now 100px wide and 200px high on stage. Now, change the code, and run it again.

foo.rotation = 90;
foo.height = 100;
trace(foo.height);

Unexpectedly, this also returns 200. It should rotate the clip and then apply the vertical scale resulting in a shape that is 100px high and 200px wide on stage. The visual result is identical to the above, when it shouldn’t be.

foo.rotation = 90;
foo.height = 100;
foo.height = 100;
trace(foo.height);

Even stranger, this does trace 100. Unfortunately, the object has been scaled both vertically and horizontally, and is now 100x100px, when it should be 200px wide and 100px high. Seems like the first height assignment gets applied before the rotation, and the second gets applied after the rotation.

Click here to see a (very) simple demo of this behaviour. The left and right blocks should be the same dimensions.

Freaky. I would hazard a guess that this is related to AS3’s weird hybrid of display object properties and transform matrixes.

One workaround would be to work with scaleX and scaleY instead, which are always applied to the original dimensions, and do not account for rotation.

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

23 Comments

  1. Grant,

    Are these temporal(time based)? Wondering if you are tracing values before displayList modifies the values of the displayObjects visually.

    Limited to Flash CS3? MovieClips on stage are implemented slightly differently. Stage items and items added via addChild behave slightly differently on occasion.

    Ted 🙂

  2. I personally always use scaleX/scaleY, it’s very rare that I need to rotate an object and THEN scale it to width, to me width/height are a bit backwards to begin with.

    Good find though!

  3. Ted, I don’t think it is a synchronicity issue. If you spread the last example over six frames with traces on their own frames in between, you will see the same behaviour. If you reset rotation to 0 and height to 200 in frame 1 at the beginning and then let it loop, it will repeat the behaviour.

  4. There’s also a bug closely related (i.e. rotating a resizing) in AS 2.0.

    “Unexpectedly, this also returns 200. It should rotate the clip and then apply the vertical scale resulting in a shape that is 100px high and 200px wide on stage. The visual result is identical to the above, when it shouldn’t be.”

    I disagree with this (or I can see some confusion here). When and object is rotated, does that actually change what its height property defines? When you lie down, is your height now not measured from your feet to your head?. Rotate a clip 45 degrees, is its height now from corner to corner?

    I would say no. I think the height and width properties should persist and always take affect in the same way and not changing depending on its rotation. Therefore after rotating a clip 90 degrees and changing its height property should look like your affecting its width. This would at least void the sort of confusion that adds to a bug like this. i.e. at what point of rotation do you start changing how the property affects the object.

  5. @Tink > I agree with you. The width and height must always be the same even the object is rotated. We have getBounds/getRect methods to acquire boundaries of the rectangle that contains the rotated object. I always deplored it too. But it is probably something that relies on Flash player history. I secretly hoped that VM2 will correct this, but it seems it cannot (if you want the real height/width of the rotated object you need to change its rotation first and give its initial rotation back).

    @Grant> Note that TextField object (AS2 and AS3) have the same first and second behaviors that you note for your clip but for the third behavior I obtain what you expect for your clip. Returned value for the TextField width is 100 and visually the TextField on the Stage is 100 wide and 200 high.

  6. Tink – I’m not saying the behaviour is great, but it’s what we’re stuck with for the foreseeable future. width and height have always referred to the boundary dimensions with rotation applied, and it’s unlikely Adobe will break that behaviour any time soon when they chose to leave it as is in AVM2.

    Tek – interesting. Thanks for pointing that out.

  7. Sorry bud I wasn’t trying to imply you thought the behaviour was great, although I did get the impression that you thought that the height and width properties should change how they effect the instance as its rotated.

    I believe this is why it currently is buggy, it doesn’t really make any sense in real terms, and at what point hould those properties swap, at 45 degrees?

  8. I seem to have found another AS3 bug, involving the ContextMenu, ExternalInterface, and browser scrollbar.

    In short, ExternalInterface stops updating while the browser scrollbar is being dragged only AFTER a right-click (ContextMenu). Before that, it works fine. Its driving me batty.

    http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=15&catid=288&threadid=1294106&enterthread=y

    Does anyone know approximately how long it can take Adobe to address/remedy discovered bugs?

  9. Sorry, the problem seems to be javascript related. Further tests have shown that the problem doesn’t exist in Firefox, and that there’s an entirely diff problem in IE7.

  10. And finally it is a Safari exlusive issue!

  11. A slightly different issue, yet kind of related, that I found a couple weeks ago. If you apply an identity matrix to a display object then rotate the object (any amount) the object will disappear. It seems that once you apply a transform matrix the if d=1 and b=0 you can’t rotate the object using the rotation property.

  12. found this bug some time ago in as2.. i’ve ommited it with xscale and yscale.. i needed to collect all the runtime transformations of movieclips and recreate them later.. it was a pain in the ass.. (not)nice to know that as2 has the same bug

  13. I’ve encountered a bug regarding Flash’s improper handling of _rotation values greater than 32,768 degrees. You can read about it here if interested:

    http://www.pixelwit.com/blog/2008/01/02/flash-rotation-bug/

  14. I simply store the rotation, reset it to 0, scale and rotate back.

    It’s the most reliable solution.

  15. This helped a lot!! ^.^

    THANK YOU!!!

  16. That bug has cost me an entire day so far. I’ve got a 1px tall rectangular shape, which I have rotated on stage inside another movieclip and then trying to adjust the width of it. I get the most random results, when I try to change the width, it seems to change the height of the rectangle so it’s not 1px anymore and certainly not giving me the width I have asked for? Very very weird.

  17. var referenceRect = rotatedObject.getRect(this);

    referenceRect.width return good numbers :).

  18. Yes, it is a real problem. In AS2.0 you can reset the bounding box(the Matrix parameters) with the object appearance remaining the same, but in AS3.0 you cant do this. Its not good(

  19. I am so glad I found this post. I have this happening and I thought I was going crazy. Unbelievable bug…

  20. I found an interesting work around for this bug. I am working on a game where the length of a rectangular object is based on how long you hold a button down and point in the direction of the rotation of another object. Basically I used multiplication instead of addition to the width of an object. For example

    this.width = ((this.width * _buttonHoldLength) / _buttonHoldLength) * _whateverVarYouWant))

    after I divided by _buttonHoldLength I was able to multiply, add or divide as I wanted. This is definitely a bug but this was the best work around I could come up with after 3 days of messing around.

  21. Flip Issue:
    In As3 while scripting game i’m getting one issue (ie) when i fliping particular MC to horizontally as well increasing that same MC scale size that particular MC increase abnormally and taking that that negative value plz solve my issue..
    Mc.scaleX=-1;

Comments are closed.