代码改变世界

AIR有陷进,大家须小心

2011-02-16 10:48  hbb  阅读(369)  评论(0编辑  收藏  举报

DisplayObject.getRect(targetCoordinateSpace:DisplayObject):Rectangle

用过的人都明白,该方法用来取显示对象的外切矩形,参数是参照坐标系。 
顺便说一下,它和getBounds的区别在于,getBounds返回的矩形还包含了对描边线条的计算。
另外,两者对使用滤镜,所产生的变化无视。这个要用 BitmapData.generateFilterRect

言归正传,AIR在这上有陷阱。

当一个child在一个mc中,child.getRect(mc),返回的应该是child位于mc的所在矩形。
在一般情况下是没错,但当mc不在显示列表对象中时,AIR就出问题了。这个时候返回的矩形会无视参数,而以自身为准,即使他的parent是mc。

由此猜想,AIR的显示列表和FP的实现还不尽相同...

测试代码

package 
{
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author hbb
	 */
	public class Main extends Sprite 
	{
		public function Main():void 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			mcInDisplayList();
			mcNotInDisplayList();
		}
		
		private function mcNotInDisplayList():void 
		{
			trace('mc Not InDisplayList');
			var child:Sprite = createRect(10, 10, new Rectangle(0, 0, 100, 100), 0xff);
			var mc:Sprite = createRect(0, 0, new Rectangle(0, 0, 100, 100), 0x00);
			mc.addChild(child);
			
			trace(' child.getRect(mc):', child.getRect(mc)); // air:(x=0, y=0, w=100, h=100)    not air:(x=10, y=10, w=100, h=100)
		}
		
		private function mcInDisplayList():void 
		{
			trace('mcInDisplayList');
			var child:Sprite = createRect(10, 10, new Rectangle(0, 0, 100, 100), 0xff);
			var mc:Sprite = createRect(0, 0, new Rectangle(0, 0, 100, 100), 0x00);
			mc.addChild(child);
			addChild(mc);
			
			trace(' child.getRect(mc):', child.getRect(mc)); // (x=10, y=10, w=100, h=100)
		}

		
		private function createRect(x:Number, y:Number, rect:Rectangle,color:uint,alpha:Number=1.0):Sprite
		{
			var s:Sprite = new Sprite();
			s.graphics.beginFill(color, alpha);
			s.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
			s.graphics.endFill();
			s.x = x;
			s.y = y;
			return s;
		}
		
	}
	
}