getBounds() on DisplayObject not functioning properly

0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

Well in fact, it is… or is it not ? depends on how you see it.

The trouble

If using masks or objects that have their “visible” property on true but “alpha” at 0.0, it is taken into account into the calculation of the bounding rectangle. Even objects that are outside of the masked area are added to it.

The solution(s)

  1. During my search, I found a post from David Barlia: http://studio.barliesque.com/blog/2008/10/the-trouble-with-getbounds/. He uses a custom technique to approximately calculate the bounding area of a DisplayObject.
  2. In that same post, someone proposed to use BitmapData to do so. Its code didn’t suit my needs so I wrote my own that takes into account the fact that the 0,0 coordinates in a DisplayObject is not always the upper left corner of it.

[sourcecode language=’as3′]
public static function getRealBounds(displayObject:DisplayObject):Rectangle
{
var bounds:Rectangle;
var boundsDispO:Rectangle = displayObject.getBounds( displayObject );

var bitmapData:BitmapData = new BitmapData( int( boundsDispO.width + 0.5 ), int( boundsDispO.height + 0.5 ), true, 0 );

var matrix:Matrix = new Matrix();
matrix.translate( -boundsDispO.x, -boundsDispO.y);

bitmapData.draw( displayObject, matrix, new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );

bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0xFF000000 );
bounds.x += boundsDispO.x;
bounds.y += boundsDispO.y;

bitmapData.dispose();
return bounds;
}
[/sourcecode]

Which one is best ?

Well, if you’re looking for speed, then you might want to take a look at David’s proposal. But if you’re looking for precision, mine is better.

How does it work ?

For those of you who want to understand how it works, here you go:

  • first, I get the bounds of the DisplayObject with the getBounds() function. Why ? because I need to know how big my BitmapData has to be and also because I need to know the upper left coordinates of my DisplayObject .
  • Then I simply translate my Matrix object with those coordinates to draw the DisplayObject into my BitmapData so I have the whole picture of it and not just a picture starting at 0, 0 of my DisplayObject.
  • Notice the ColorTransform object passed to the draw() function. This will colorize in red everything that is not transparent on the BitmapData.
  • This, in order to get a precise bounding rectangle calculated with this color, thanks to the getColorBoundsRect() function of BitmapData.
  • Then I add the x and y coordinates of the “original” bounding rectangle to the final one.

There might be some bugs but it works pretty well for me at the moment.
Tkx to David and his readers.

0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

5 Comments

  1. Hi Thomas,

    Thanks for sharing this code. It is really handy. I have used it to to do bitmapData.draw() on a masked movieclip. Which I was having problems with until I found your post.

    I have posted my code to Snipplr …

    http://snipplr.com/view/32341/as3-bitmapdatadraw-with-masked-displayobject/

    Cheers,

    Adrian

  2. Bill

    All I have to say is you are a life saver, this works perfectly. getBounds wasnt working for me in my situation and was always off by serveral pixels sometimes, where this works every time.

  3. Anthony

    Thanks so much. This did exactly what I needed it to do. I was wanting to find the real boundaries around a text field (the textField class always leaves padding on all sides)… getBounds just gave me dimensions of the TextField (not much more than turning the border on). Your function allowed me to shrink that border to fit the text precisely.

    Thanks!

  4. Great bit of code – just what I needed to get the bounds of a masked movieclip. Thanks. :)

Leave a Comment