var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* @module annie
*/
var annie;
(function (annie) {
/**
* 显示对象的容器类,可以将其他显示对象放入其中,是annie引擎的核心容器类.
* Sprite 类是基本显示列表构造块:一个可显示图形并且也可包含子项的显示列表节点。
* Sprite 对象与影片剪辑类似,但没有时间轴。Sprite 是不需要时间轴的对象的相应基类。
* 例如,Sprite 将是通常不使用时间轴的用户界面 (UI) 组件的逻辑基类
* @class annie.Sprite
* @extends annie.DisplayObject
* @public
* @since 1.0.0
*/
var Sprite = (function (_super) {
__extends(Sprite, _super);
function Sprite() {
var _this = _super.call(this) || this;
/**
* 是否可以让children接收鼠标事件,如果为false
* 鼠标事件将不会往下冒泡
* @property mouseChildren
* @type {boolean}
* @default true
* @public
* @since 1.0.0
*/
_this.mouseChildren = true;
/**
* 显示对象的child列表
* @property children
* @type {Array}
* @public
* @since 1.0.0
* @default []
* @readonly
*/
_this.children = [];
_this._instanceType = "annie.Sprite";
return _this;
}
Object.defineProperty(Sprite.prototype, "cacheAsBitmap", {
/**
* 是否缓存为位图,注意一但缓存为位图,它的所有子级对象上的事件侦听都将无效
* @property cacheAsBitmap
* @public
* @since 1.1.2
* @default false
* @type boolean
*/
get: function () {
return this._cacheAsBitmap;
},
set: function (value) {
var s = this;
if (!s._texture) {
//截图
s._texture = new Image();
}
if (value) {
s._texture.src = annie.toDisplayDataURL(s);
}
else {
s._texture.src = "";
s._offsetX = 0;
s._offsetY = 0;
}
s._cacheAsBitmap = value;
},
enumerable: true,
configurable: true
});
/**
* 添加一个显示对象到Sprite
* @method addChild
* @param {annie.DisplayObject} child
* @public
* @since 1.0.0
*/
Sprite.prototype.addChild = function (child) {
this.addChildAt(child, this.children.length);
};
/**
* 从Sprite中移除一个child
* @method removeChild
* @public
* @since 1.0.0
* @param {annie.DisplayObject} child
*/
Sprite.prototype.removeChild = function (child) {
var s = this;
var len = s.children.length;
for (var i = 0; i < len; i++) {
if (s.children[i] == child) {
s.removeChildAt(i);
break;
}
}
};
//全局遍历
Sprite._getElementsByName = function (rex, root, isOnlyOne, isRecursive, resultList) {
var len = root.children.length;
if (len > 0) {
var name_1;
var child = void 0;
for (var i = 0; i < len; i++) {
child = root.children[i];
name_1 = child.name;
if (name_1 && name_1 != "") {
if (rex.test(name_1)) {
resultList.push(child);
if (isOnlyOne) {
return;
}
}
}
if (isRecursive) {
if (child["children"] != null) {
Sprite._getElementsByName(rex, child, isOnlyOne, isRecursive, resultList);
}
}
}
}
};
/**
* 通过给displayObject设置的名字来获取一个child,可以使用正则匹配查找
* @method getChildByName
* @param {string} name 对象的具体名字或是一个正则表达式
* @param {boolean} isOnlyOne 默认为true,如果为true,只返回最先找到的对象,如果为false则会找到所有匹配的对象数组
* @param {boolean} isRecursive false,如果为true,则会递归查找下去,而不只是查找当前对象中的child,child里的child也会找,依此类推
* @returns {any} 返回一个对象,或者一个对象数组,没有找到则返回空
* @public
* @since 1.0.0
*/
Sprite.prototype.getChildByName = function (name, isOnlyOne, isRecursive) {
if (isOnlyOne === void 0) { isOnlyOne = true; }
if (isRecursive === void 0) { isRecursive = false; }
if (!name)
return null;
var s = this;
var rex;
if (typeof (name) == "string") {
rex = new RegExp("^" + name + "$");
}
else {
rex = name;
}
var elements = [];
Sprite._getElementsByName(rex, s, isOnlyOne, isRecursive, elements);
var len = elements.length;
if (len == 0) {
return null;
}
else if (len == 1) {
return elements[0];
}
else {
return elements;
}
};
/**
* 添加一个child到Sprite中并指定添加到哪个层级
* @method addChildAt
* @param {annie.DisplayObject} child
* @param {number} index 从0开始
* @pubic
* @since 1.0.0
*/
Sprite.prototype.addChildAt = function (child, index) {
if (!child)
return;
var s = this;
var sameParent = (s == child.parent);
var len;
if (child.parent) {
if (!sameParent) {
child.parent.removeChild(child);
}
else {
len = s.children.length;
for (var i = 0; i < len; i++) {
if (s.children[i] == child) {
s.children.splice(i, 1);
break;
}
}
}
}
child.parent = s;
len = s.children.length;
if (index >= len) {
s.children.push(child);
}
else if (index == 0) {
s.children.unshift(child);
}
else {
s.children.splice(index, 0, child);
}
if (s.stage && !sameParent) {
child["_cp"] = true;
child._onDispatchBubbledEvent("onAddToStage");
}
};
/**
* 获取Sprite中指定层级一个child
* @method getChildAt
* @param {number} index 从0开始
* @pubic
* @since 1.0.0
* @return {annie.DisplayObject}
*/
Sprite.prototype.getChildAt = function (index) {
if ((this.children.length - 1) >= index) {
return this.children[index];
}
else {
return null;
}
};
/**
* 获取Sprite中一个child所在的层级索引,找到则返回索引数,未找到则返回-1
* @method getChildIndex
* @param {annie.DisplayObject} child 子对象
* @pubic
* @since 1.0.2
* @return {number}
*/
Sprite.prototype.getChildIndex = function (child) {
var len = this.children.length;
for (var i = 0; i < len; i++) {
if (this.children[i] == child) {
return i;
}
}
return -1;
};
/**
* 调用此方法对Sprite及其child触发一次指定事件
* @method _onDispatchBubbledEvent
* @private
* @param {string} type
* @param {boolean} updateMc 是否更新movieClip时间轴信息
* @since 1.0.0
*/
Sprite.prototype._onDispatchBubbledEvent = function (type, updateMc) {
if (updateMc === void 0) { updateMc = false; }
var s = this;
var len = s.children.length;
if (type == "onRemoveToStage" && !s.stage)
return;
s.stage = s.parent.stage;
for (var i = 0; i < len; i++) {
s.children[i]._onDispatchBubbledEvent(type, updateMc);
}
_super.prototype._onDispatchBubbledEvent.call(this, type, updateMc);
};
/**
* 移除指定层级上的孩子
* @method removeChildAt
* @param {number} index 从0开始
* @public
* @since 1.0.0
*/
Sprite.prototype.removeChildAt = function (index) {
var s = this;
var child;
var len = s.children.length - 1;
if (len < 0)
return;
if (index == len) {
child = s.children.pop();
}
else if (index == 0) {
child = s.children.shift();
}
else {
child = s.children.splice(index, 1)[0];
}
child._onDispatchBubbledEvent("onRemoveToStage");
child.parent = null;
};
/**
* 移除Sprite上的所有child
* @method removeAllChildren
* @public
* @since 1.0.0
*/
Sprite.prototype.removeAllChildren = function () {
var s = this;
var len = s.children.length;
for (var i = len - 1; i >= 0; i--) {
s.removeChildAt(0);
}
};
/**
* 重写刷新
* @method update
* @public
* @param isDrawUpdate 不是因为渲染目的而调用的更新,比如有些时候的强制刷新 默认为true
* @since 1.0.0
*/
Sprite.prototype.update = function (isDrawUpdate) {
if (isDrawUpdate === void 0) { isDrawUpdate = false; }
var s = this;
if (!s._visible)
return;
_super.prototype.update.call(this, isDrawUpdate);
if (!s._cacheAsBitmap) {
var len = s.children.length;
var child = void 0;
var maskObjIds = [];
for (var i = len - 1; i >= 0; i--) {
child = s.children[i];
if (!s._visible)
continue;
//更新遮罩
if (child.mask && (maskObjIds.indexOf(child.mask.instanceId) < 0)) {
var childChild = null;
child.mask.parent = s;
if (s.totalFrames && child.mask.totalFrames) {
child.mask.gotoAndStop(s.currentFrame);
//一定要为true
childChild = child.mask.getChildAt(0);
if (childChild) {
childChild.isUseToMask = true;
childChild.hitTestWidthPixel = false;
}
}
else {
child.mask.isUseToMask = true;
child.mask.hitTestWidthPixel = false;
}
child.mask._cp = true;
child.mask.update(isDrawUpdate);
child.mask.isUseToMask = false;
if (childChild) {
childChild.isUseToMask = false;
}
maskObjIds.push(child.mask.instanceId);
}
child.update(isDrawUpdate);
}
}
s._UI.UM = false;
s._UI.UA = false;
s._UI.UF = false;
};
/**
* 重写碰撞测试
* @method hitTestPoint
* @param {annie.Point} globalPoint
* @param {boolean} isMouseEvent
* @returns {any}
* @public
* @since 1.0.0
*/
Sprite.prototype.hitTestPoint = function (globalPoint, isMouseEvent) {
if (isMouseEvent === void 0) { isMouseEvent = false; }
var s = this;
if (!s._visible)
return null;
if (isMouseEvent && !s.mouseEnable)
return null;
if (!s._cacheAsBitmap) {
var len = s.children.length;
var hitDisplayObject = void 0;
var child = void 0;
//这里特别注意是从上往下遍历
for (var i = len - 1; i >= 0; i--) {
child = s.children[i];
if (child.mask) {
//看看点是否在遮罩内
if (!child.mask.hitTestPoint(globalPoint, isMouseEvent)) {
//如果都不在遮罩里面,那还检测什么直接检测下一个
continue;
}
}
hitDisplayObject = child.hitTestPoint(globalPoint, isMouseEvent);
if (hitDisplayObject) {
return hitDisplayObject;
}
}
}
else {
//如果都不在缓存范围内,那就更不在矢量范围内了;如果在则继续看
var p = s.globalToLocal(globalPoint);
var image = s._texture;
if (!image || image.width == 0 || image.height == 0) {
return null;
}
var _canvas = annie.DisplayObject["_canvas"];
_canvas.width = 1;
_canvas.height = 1;
p.x -= s._offsetX;
p.y -= s._offsetY;
var ctx = _canvas["getContext"]('2d');
ctx.clearRect(0, 0, 1, 1);
ctx.setTransform(1, 0, 0, 1, -p.x, -p.y);
ctx.drawImage(image, 0, 0);
if (ctx.getImageData(0, 0, 1, 1).data[3] > 0) {
return s;
}
}
return null;
};
/**
* 重写getBounds
* @method getBounds
* @returns {any}
* @since 1.0.0
* @public
*/
Sprite.prototype.getBounds = function () {
var s = this;
var rect = s._bounds;
rect.x = 0;
rect.y = 0;
rect.width = 0;
rect.height = 0;
if (!s._cacheAsBitmap) {
var len = s.children.length;
if (len > 0) {
for (var i = 0; i < len; i++) {
if (s.children[i].visible)
annie.Rectangle.createFromRects(rect, s.children[i].getDrawRect());
}
if (s.mask) {
var maskRect = s.mask.getDrawRect();
if (rect.x < maskRect.x) {
rect.x = maskRect.x;
}
if (rect.y < maskRect.y) {
rect.y = maskRect.y;
}
if (rect.width > maskRect.width) {
rect.width = maskRect.width;
}
if (rect.height > maskRect.height) {
rect.height = maskRect.height;
}
}
}
}
else {
if (s._texture) {
rect.x = s._offsetX;
rect.y = s._offsetY;
rect.width = s._texture.width;
rect.height = s._texture.height;
}
}
return rect;
};
/**
* 重写渲染
* @method render
* @param {annie.IRender} renderObj
* @public
* @since 1.0.0
*/
Sprite.prototype.render = function (renderObj) {
var s = this;
if (s._cp)
return;
if (s._cacheAsBitmap) {
_super.prototype.render.call(this, renderObj);
}
else {
if (s.cAlpha > 0 && s._visible) {
var maskObj = void 0;
var child = void 0;
var len = s.children.length;
for (var i = 0; i < len; i++) {
child = s.children[i];
if (child.cAlpha > 0 && child._visible) {
if (maskObj) {
if (child.mask) {
if (child.mask != maskObj) {
renderObj.endMask();
maskObj = child.mask;
renderObj.beginMask(maskObj);
}
}
else {
renderObj.endMask();
maskObj = null;
}
}
else {
if (child.mask) {
maskObj = child.mask;
renderObj.beginMask(maskObj);
}
}
child.render(renderObj);
}
}
if (maskObj) {
renderObj.endMask();
}
}
}
};
return Sprite;
}(annie.DisplayObject));
annie.Sprite = Sprite;
})(annie || (annie = {}));