scale9Grid and Bitmaps - do they work together or not?
I'm not yet used to Flash IDE environment, so I write pure code in FlashDevelop. I got sprite of various graphical assets, one of which was meant to be used with that hugely useful scale9Grid feature... It didn't work. Since I was doing it first time in my life, I thought I screwed something, but then I tried drawRoundRect and beginFill (rather then beginBitmapFill) and it worked as expected. My logical thought was that it doesn't work with bitmaps (despite of the fact that on Adobe Livedocs example they use a picture of the orangoutang to demonstrate scale9Grid capabilities).
After that I read variety of opinions starting with "it works just fine" and ending with "it doesn't work, screw you Adobe". So I'm curious now, does it work or it doesn't?
I've found how I can specify s开发者_C百科cale9Grid parameters right in Embed statement, but my embed image is sprite. I guess it won't work with it anyway, right?
After digging into the [Embed] tag and analyzing it's approach I figured out how to do scale9Grid without a pile of Bitmaps or re-drawing graphics each time you resize.
scale9Grid only effects the drawing API graphics (or the Graphics objects) - not Bitmaps directly. So you have to draw your bitmap to the graphics object of a Shape or Sprite:
shape.graphics.beginBitmapFill(bitmapData);
The trick is to do a separate fill for each slice, but only this first time:
var rect:Rectangle = new Rectangle(20, 20, 60, 10);
var gridX:Array = [rect.left, rect.right, bitmapData.width];
var gridY:Array = [rect.top, rect.bottom, bitmapData.height];
shape.graphics.clear();
var left:Number = 0;
for (var i:int = 0; i < 3; i++) {
var top:Number = 0;
for (var j:int = 0; j < 3; j++) {
shape.graphics.beginBitmapFill(bitmapData);
shape.graphics.drawRect(left, top, gridX[i] - left, gridY[j] - top);
shape.graphics.endFill();
top = gridY[j];
}
left = gridX[i];
}
shape.scale9Grid = rect;
Remember to do an endFill() or it's not going to work. After preparing the shape you just need to add your scale9Grid Rectangle and you're all set - perfect bitmap scaling without extra display objects or continually redrawing.
I banged my head against scale grid until found this article. Scale grid has a lot of limitations, if they aren't meet it's not applied. If you can't work around them, here is 9-bitmap approach: ScaleObject.
Bitmaps will not work with scale9Grid unless you split the bitmaps up. You can also use custom classes that will do the work of splitting the bitmaps up for you.
http://www.dreaminginflash.com/2007/12/03/9-slice-and-bitmap/
UPDATE:
About understanding the scaling. Look at this image. The red parts will be scaled if needed.
Nice snippet, Tyler Wright!
Some optimize:
static public function drawAndScale9Grid(s : Shape, bitmapData : BitmapData, rect : Rectangle) : void {
const gridX : Vector.<Number> = Vector.<Number>([rect.left, rect.right, bitmapData.width]);
const gridY : Vector.<Number> = Vector.<Number>([rect.top, rect.bottom, bitmapData.height]);
const g : Graphics = s.graphics;
g.clear();
var left : Number = 0;
var i : int, j : int;
const n : uint = gridX.length, m : uint = gridY.length;
while(i < n) {
j = 0; // reset j
var top : Number = 0;
while(j < m) {
// draw shape with special coords of bitmapdata
g.beginBitmapFill(bitmapData);
g.drawRect(left, top, gridX[i] - left, gridY[j] - top);
g.endFill();
top = gridY[j];
j++;
}
left = gridX[i];
i++;
}
s.scale9Grid = rect;
}
精彩评论