moock.org is supported in part by



Flash MX 2004 now shipping! Buy it here...
(Your purchase will help support moock.org.)
-->

May 25, 2009

get visible width/height of a display object

When it comes to the width and height variables of ActionScript's DisplayObject, what you see is not always what you get. For example, consider the following code, which draws a 50x75 rectangle at position (10, 10) in a Sprite, and then masks it with a 40-pixel-diameter circle:

// The mask
var maskShape:Sprite = new Sprite();
maskShape.graphics.beginFill(0);
maskShape.graphics.drawCircle(20, 20, 20);
addChild(maskShape);
// The rectangle
var rect:Sprite = new Sprite();
rect.graphics.beginFill(0xFF0000);
rect.graphics.drawRect(10, 10, 50, 75);
rect.mask = maskShape;
// Give the rectangle a parent
addChild(rect);

If we check, the "width" and "height" variables of "rect", we get 50 and 75, even though "rect" is masked.

trace(rect.width);   // 50
trace(rect.height);  // 75

But the "rect" object's width and height variables contradict what you see on screen:

On screen, the preceding graphic measures only 40 by 40 (the diameter of the circular mask).

The DisplayObject class's width and height variables can also seem misleading when a DisplayObjectContainer holds non-visible children. For example, the following code creates a container with two children, one of which is non-visible.

// The circle
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0);
circle.graphics.drawCircle(10, 10, 10);
// The non-visible rectangle
var rect:Sprite = new Sprite();
rect.graphics.beginFill(0xFF0000);
rect.graphics.drawRect(10, 10, 50, 75);
rect.visible = false;
// The container
var container:Sprite = new Sprite();
container.addChild(circle);
container.addChild(rect);
// Give the container a parent
addChild(container);

If we check, the "width" and "height" variables of "container", we get 60 and 85, even though "rect" is non-visible:

trace(container.width);   // 60
trace(container.height);  // 85

Again, the "container" object's width and height variables contradict what you see on screen:

On screen, the preceding graphic measures only 20 by 20 (the diameter of the circle).

As a final example of misleading width and height values, consider the following code, which creates a simple text field:

var t:TextField = new TextField();
t.text = "hi there"
addChild(t);

If we check, the "width" and "height" variables of "t", we get 100 and 100--the dimensions of the TextField object's bounding box, even though that bounding box is not visible:

trace(t.width);   // 100
trace(t.height);  // 100

The TextField object's width and height variables again contradict what you see on screen:

On screen, the preceding graphic measures only 37 by 12 (the dimensions of the visible text, not the bounding box).

So what do you do if you need to know the dimensions of what's actually visible on screen? Unfortunately, in ActionScript, there's no convenient way to find that information. I've logged a bug with Adobe requesting that they add one. But until then, the only option is to copy your desired display object to a bitmap and measure the occupied pixels. I did just that on a recent MegaPhone project; you can grab the code below. Note, however, that the bitmap approach is slower than a native implementation would be, so if you use the code, all I ask is that you please vote for the preceding bug. Thanks!

/**
 * Returns the distance from the registration point of the specified 
 * object to the bottom-most visible pixel, ignoring any region
 * that is not visible due to masking. For example, if a display
 * object contains a 100-pixel-high shape and a 50-pixel-high mask,
 * getVisibleHeight() will return 50, whereas DisplayObject's
 * "height" variable would yield 100. 
 * 
 * The maximum measureable dimensions of the supplied object is
 * 2000x2000.
 */
function getVisibleHeight (o:DisplayObject):Number {
  var bitmapDataSize:int = 2000;
  var bounds:Rectangle;
  var bitmapData:BitmapData = new BitmapData(bitmapDataSize, 
                                             bitmapDataSize,
                                             true,
                                             0);
  bitmapData.draw(o);
  bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0x00000000, false );
  bitmapData.dispose(); 
  return bounds.y + bounds.height;
}
/**
 * Returns the distance from the registration point of the specified 
 * object to the right-most visible pixel, ignoring any region
 * that is not visible due to masking. For example, if a display
 * object contains a 100-pixel-wide shape and a 50-pixel-wide mask,
 * getVisibleWidth() will return 50, whereas DisplayObject's
 * "width" variable would yield 100. 
 * 
 * The maximum measureable dimensions of the supplied object is
 * 2000x2000.
 * 
 * @since MegaPhone App Framework 1.0
 */
function getVisibleWidth (o:DisplayObject):Number {
  var bitmapDataSize:int = 2000;
  var bounds:Rectangle;
  var bitmapData:BitmapData = new BitmapData(bitmapDataSize, 
                                             bitmapDataSize, 
                                             true, 
                                             0);
  bitmapData.draw(o);
  bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0x00000000, false );
  bitmapData.dispose(); 
  return bounds.x + bounds.width;
}

[Updates May 26, 2009: 1) Made the code faster based on an observation by Mario Klingemann. 2) Added the TextField example.]

posted by moock at 10:58 PM | Comments (10)

May 21, 2009

can't enable gpu acceleration in flex builder/mxmlc

while working with a colleague at megaphone, it recently came to my attention that there is currently no way to enable hardware acceleration at the .swf level with flex builder 3 or the flex framework's standalone compiler, mxmlc. hence, a .swf file compiled via the flex framework or mxmlc currently cannot use hardware acceleration when running in the standalone version of flash player.

i logged a bug as soon as i confirmed the compiler-option omission with flex builder product manager, matt chotin. please vote for it if you'd like to see this issue addressed. matt's comments on the bug seem encouraging; he indicates that the option could be added to the flex framework's 3.4 and 4.0 versions within the 4.0 development cycle. until then, if you're desperate, you'll have to write a post-compiler tool to set the appropriate swf tag options yourself. such a tool could be written as an air app, based on thibault imbert's SWFExplorer.

mr. chotin said that flex builder 4 (now "flash builder 4") likely won't have a gui option to enable hardware acceleration, but that it might provide support via the project properties dialog's "additional compiler arguments" field.

note that in flex builder 3, hardware acceleration *can* be enabled for .swf files running in a browser by adding the appropriate wmode attribute setting in your project's html template's .swf-object/embed tags.

posted by moock at 04:18 PM

May 01, 2009

Announcing USER1 and Union

three days ago at fitc, derek clayton and i announced the launch of USER1 Subsystems Corporation and the Union Platform, a platform for creating multiuser applications. Union Alpha 1 is now available for download.

USER1 is working in an exclusive partnership with Play MegaPhone Inc to create a network of big-screen, multiuser applications you control with a phone call. like shoot 'em up in Times Square or trivia at an NBA Allstar game.

posted by moock at 01:17 AM

April 24, 2009

the lost actionscript 3.0 weekend

i finally decided to break the print tradition and make an actionscript
training dvd with o'reilly. but it's not your average training video. we
wanted to capture the energy of a programming session with a group of
fun and passionate friends. so james paterson, hoss gifford, and i
locked ourselves away in a cabin by the ocean for a three-day weekend to
shoot an eleven-hour crash course on object-oriented programming. you
can take a look at the results here...

trailers:
>> trailer 1
>> trailer 2 (hoss profile)
>> trailer 3 (james profile)

free course content:
>> course 1 introduction
>> object references and garbage collection
>> inheritance
>> graphics programming with flash player engineer jim corbett
>> flash/flex workflow

the physical dvd will be available very soon, and you can already watch the
entire two-part course online.

>> watch at safari
>> watch at o'reilly

this is a brand-new format for an actionscript training video, so we'd
love to hear what you think. does it work for you as a way to learn? is
it more engaging than the standard "screencast" training style? (we sure
hope so!) post a comment or send me an email (colin@moock.org) to tell me what you think. or you can post a public comment about the video on insideria.

if you are planning on purchasing the video, you should do so through this link:

http://www.oreilly.com/go/law

it gives you a 20-40% discount, depending on what you order. if you're linking to the video, please use that link so everyone can get the discount (o'reilly's main catalog page has the expensive version...)

posted by moock at 04:04 PM | Comments (16)

April 05, 2009

get number of bytes in a UTF-8 string

Here's a handy little ActionScript function that reports the number of bytes in a UTF-8 encoded string (the default encoding for ActionScript):

public function getNumBytesUTF8 (s:String):Number {
  var byteArray:ByteArray = new ByteArray();
  byteArray.writeUTFBytes(s);
  return byteArray.length;
}
// Usage:
trace(getNumBytesUTF8("automobile"));  // 10
trace(getNumBytesUTF8("車"));          // 3

Note: "number of bytes" is not the same thing as "number of characters". For "number of characters," use the String class's length variable:

trace("車".length); // 1
posted by moock at 08:39 PM

March 25, 2009

James Paterson's new work

dear james,
thank you for reminding us all (or me at least) why we do this.

>> view The Rotten Fruit Tardis
>> read about Harvest at bitforms

i'm looking forward to seeing this in person at fitc.

posted by moock at 04:21 PM

March 17, 2009

FITC toronto 2009

[UPDATE: Shawn Pucknell, founder of FITC, just gave me a discount code for all moockblog readers! Use code "moock" to get 20% off when you register for FITC.]

fitc is coming up in april (25th-28th). in my presentation i'll officially be revealing what's kept me occupied for nearly every minute of the past 8 months. for a complete list of the always-inspiring sessions at the conference, visit FITC's presentation list.

i highly recommend attending fitc. it's one of the flash industry's best places to find world-class training, inspiration, and business opportunities--all crammed into an intense 3-day pressure cooker. hope to see you there!

posted by moock at 12:16 AM