Skip to content

Instantly share code, notes, and snippets.

@profelis
Created July 25, 2012 07:42
Show Gist options
  • Save profelis/3174960 to your computer and use it in GitHub Desktop.
Save profelis/3174960 to your computer and use it in GitHub Desktop.
Starling Scale9Image (auto update)
package deep.step.targets.starling.tools
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.geom.Rectangle;
import starling.core.RenderSupport;
import starling.display.Image;
import starling.display.Sprite;
import starling.textures.Texture;
import starling.textures.TextureSmoothing;
/**
* @author Dima Granetchi <[email protected]>, <[email protected]>
*/
public class Scale9Image extends Sprite
{
private var _bitmapData:BitmapData;
private var _sliceRect:Rectangle;
private var w:int;
private var h:int;
private var images:Vector.<Vector.<Image>>;
private var textures:Vector.<Vector.<Texture>>;
private var texture:Texture;
private var _smoothing:String = TextureSmoothing.BILINEAR;
private var _invalid:Boolean;
public function Scale9Image(bitmap:BitmapData, sliceRect:Rectangle = null)
{
textures = new Vector.<Vector.<Texture>>(3, true);
images = new Vector.<Vector.<Image>>(3, true);
for (var i:int = 0; i < 3; i++)
{
textures[i] = new Vector.<Texture>(3, true);
images[i] = new Vector.<Image>(3, true);
}
this.bitmapData = bitmap;
this.sliceRect = sliceRect;
}
public static function fromBitmapData(bitmap:BitmapData, sliceRect:Rectangle):Scale9Image
{
return new Scale9Image(bitmap, sliceRect);
}
public static function fromDisplayObject(displayObject:DisplayObject, rect:Rectangle = null,
smoothing:Boolean = true):Scale9Image
{
var b:BitmapData = new BitmapData(displayObject.width, displayObject.height, true, 0x00000000);
b.lock();
b.draw(displayObject, null, null, null, null, smoothing);
return new Scale9Image(b, rect || displayObject.scale9Grid);
}
private function update():void
{
unflatten();
var cols:Array = [0, _sliceRect.left, _sliceRect.right, _bitmapData.width];
var rows:Array = [0, _sliceRect.top, _sliceRect.bottom, _bitmapData.height];
var dCols:Array = [0, _sliceRect.left, w - _bitmapData.width + _sliceRect.right, w];
var dRows:Array = [0, _sliceRect.top, h - _bitmapData.height + _sliceRect.bottom, h];
var origin:Rectangle = new Rectangle();
var draw:Rectangle = new Rectangle();
for (var cx:int = 0; cx < 3; cx++)
{
for (var cy:int = 0; cy < 3; cy++)
{
origin.setTo(cols[cx], rows[cy], cols[cx + 1] - cols[cx], rows[cy + 1] - rows[cy]);
draw.setTo(dCols[cx], dRows[cy], dCols[cx + 1] - dCols[cx], dRows[cy + 1] - dRows[cy]);
var t:Texture = Texture.fromTexture(texture, origin);
textures[cx][cy] = t;
var image:Image = images[cx][cy];
if (image)
{
image.texture.dispose();
image.texture = t;
}
else
{
images[cx][cy] = image = new Image(t);
addChild(image);
}
image.x = draw.x;
image.y = draw.y;
image.smoothing = _smoothing;
if (cx == 1) image.scaleX = draw.width / origin.width;
if (cy == 1) image.scaleY = draw.height / origin.height;
}
}
flatten();
_invalid = false;
}
public function resize(w:int, h:int):void
{
this.w = w;
this.h = h;
_invalid = true;
}
override public function dispose():void
{
if (texture) texture.dispose();
for (var cx:int = 0; cx < 3; cx++)
{
for (var cy:int = 0; cy < 3; cy++)
{
if (textures[cx][cy]) textures[cx][cy].dispose();
}
}
super.dispose();
_bitmapData = null;
images = null;
texture = null;
textures = null;
}
public function get bitmapData():BitmapData
{
return _bitmapData;
}
public function set bitmapData(value:BitmapData):void
{
if (value == null)
throw new ArgumentError("bitmapData can't be null");
if (_bitmapData != value)
{
if (texture) texture.dispose();
_bitmapData = value;
texture = Texture.fromBitmapData(_bitmapData);
_invalid = true;
}
}
public function get sliceRect():Rectangle
{
return _sliceRect;
}
public function set sliceRect(value:Rectangle):void
{
if (value == null) throw new ArgumentError("sliceRect cant be null");
if (!_sliceRect || !_sliceRect.equals(value))
{
_sliceRect = value;
_invalid = true;
}
}
public function get smoothing():String
{
return _smoothing;
}
public function set smoothing(value:String):void
{
if (TextureSmoothing.isValid(value))
{
_smoothing = value;
_invalid = true;
}
else
throw new ArgumentError("Invalid smoothing mode: " + value);
}
override public function render(support:RenderSupport, parentAlpha:Number):void
{
if (_invalid) update();
super.render(support, parentAlpha);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment