I’m having trouble drawing a Label component to a BitmapData object. No matter what I try, the label never shows up. Everything works fine if I simply add the Label to the display list, but for performance reasons, that is not an option. I’m not having any trouble drawing other kinds of things ( vector art ) to BitmapData, but this Label is really throwing me for a loop.
I’ve had this problem with both the spark.components.Label and mx.controls.Label. I feel like this should work, since both of these classes extend UIComponent, which implements IBitmapDrawable, but I’m not super familiar with the Flex framework, so maybe I’m missing out on something. Anyone have any ideas?
I’ll share the relevant Actionscript and CSS I’m using.
AS:
_label = new Label();
_label.styleName = "categoryButton";
_label.width = 500;
_label.height = 40;
_label.text = "LABEL TEXT";
var bd:BitmapData = new BitmapData( 500, 500, true, 0 );
bd.draw( _label );
_labelBitmap = new Bitmap( bd );
addChild( _labelBitmap );
CSS:
@font-face {
src: url("assets/HelveticaNeueLTStd-Roman.otf");
fontFamily: "HelveticaNeueLT-Roman";
fontStyle: normal;
fontWeight: normal;
unicode-range: U+0020-U+0040, /* Punctuation, Numbers */
U+0041-U+005A, /* Upper-Case A-Z */
U+005B-U+0060, /* Punctuation and Symbols */
U+0061-U+007A, /* Lower-Case a-z */
U+007B-U+007E; /* Punctuation and Symbols */
advancedAntiAliasing: true;
embedAsCFF: true;
}
s|Label.categoryButton {
fontFamily: "HelveticaNeueLT-Roman";
font-size:30;
fontStyle:normal;
textAlign:center;
color:#cc0000;
}
As you suspected, this has everything to do with the Flex component lifecycle. Have a look at the source code of UIComponent:
This method is called after a child component was added to the parent component and thus to the displaylist. As you can see, only then will the child component be initialized. This means nothing will be drawn until the component is added to the displaylist.
Now you might think: “OK, lets just call initialize() explicitly then.” That won’t work either. Have a look at the function that initiates the rendering:
It refers to the parent DisplayObject, which is null since the component wasn’t added to the displaylist. And there are other things after that that will fail because the component wasn’t properly created. The Flex framework will never call this method as long as the component isn’t on the displaylist and if you call it explicitly, you will get runtime errors.
Conclusion:
if you want to draw Flex components as a bitmap, you’ll have to add them to the displaylist. Or do as @divillysausages suggested and use the pure ActionScript alternative.
To be certain that the component was added to the displaylist and fully rendered, you should listen for the
FlexEvent.CREATION_COMPLETEevent (I reckon the suggestion to skip some frames is bad practice; see comments below).