Creating an easy way to make tabs for the Flash RAD framework, yesterday I encountered the following quirk in Flash.
Flash drops the 9 slice scaling when a MovieClip is used in / for a mask and treats the MovieClip as a plain clip.
Situation
Tabs heads can scale hirizontally with the label inside. Thus they occupy the space they need. In order to allow a limitless set of backgrounds for the tab sheet, I want to use the shape of the tabsheet to mask images or movieclips.
9-slice scaling
9-slice scaling is a neat option in Flash to divide a MovieClip in 9 slices: 4 for the corners, 4 for the “borders” and 1 for the center. It keeps the slant in my test-tab head intact. An example is given below.
Test:
Explenation
The first column shows the original objects.
The red masks show a nice slanted tab as intended. However, when you apply the “mask” movieclip to the background, the tab head is treated as a plain movieclip without 9-slice scaling.
I found an alternative way of masking using Bitmap clipping and copying channels with the BitmapData object. As you see in the screenshot, the green area is neatly masked as intended. The principle is this: the blue area is what I want to get rid of, the red what I want to keep. Copying the red channel to the alpha channel of the BitmapData of the background, clips everything except the area of the red shape.
Code used to test
The code used for the example above is stated here:
import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.Bitmap; // SET MASK USING MOVIECLIPS WITH 9 SLICED SCALING // MASK FAILS ON 9-SLIDE SCALING. // tabMask is the red tab in the middle background.mask=tabMask; // WORK AROUND: USING BITMAPDATA AND CHANNELS // COPY BLUE/RED MASK var tabMaskBMdata:BitmapData=new BitmapData(tabMask2.width, tabMask2.height, true); tabMaskBMdata.draw(tabMask2); // COPY BACKGROUND var tabSheetBMdata:BitmapData = new BitmapData(tabMask.width, tabMask.height, true); tabSheetBMdata.draw(background_source); // APPLY MASK: USE RED CHANNEL TO SHOW tabSheetBMdata.copyChannel(tabMaskBMdata, tabMaskBMdata.rect, new Point(0,0), BitmapDataChannel.RED, BitmapDataChannel.ALPHA); // PUT TAB ON STAGE var tabSheet:Bitmap=new Bitmap(tabSheetBMdata) tabSheet.x=515; tabSheet.y=223; this.addChild(tabSheet); // DONE
angie
July 23, 2009
Senocular found another workaround (which is a bit easier) elsewhere. I’ve tested it, and it works for me. Thought I’d share:
The workaround is to place the scale9 object in a movie clip, then set that movie clip and the movie clip to be masked to have a cacheAsBitmap = true and then apply the mask via AS.
(NOTE: You still have to scale the scale9 object WITHIN its holder movieclip, but at least it will mask properly.)