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) {
/**
* 显示对象抽象类,不能直接实例化。一切显示对象的基类,包含了显示对象需要的一切属性
* DisplayObject 类本身不包含任何用于在屏幕上呈现内容的 API。
* 因此,如果要创建 DisplayObject 类的自定义子类,您将需要扩展其中一个具有在屏幕
* 上呈现内容的 API 的子类,如 Shape、Sprite、Bitmap、TextField 或 MovieClip 类。
* @class annie.DisplayObject
* @since 1.0.0
* @extends annie.EventDispatcher
*/
var DisplayObject = (function (_super) {
__extends(DisplayObject, _super);
/**
* @method DisplayObject
* @since 1.0.0
* @public
*/
function DisplayObject() {
var _this = _super.call(this) || this;
/**
* 更新信息
* @property _UI
* @param UM 是否更新矩阵 UA 是否更新Alpha UF 是否更新滤镜
*/
_this._UI = { UD: false, UM: true, UA: true, UF: false };
/**
* 此显示对象所在的舞台对象,如果此对象没有被添加到显示对象列表中,此对象为空。
* @property stage
* @public
* @since 1.0.0
* @type {Stage}
* @default null;
* @readonly
* */
_this.stage = null;
/**
* 显示对象的父级
* @property parent
* @since 1.0.0
* @public
* @type {annie.Sprite}
* @default null
* @readonly
*/
_this.parent = null;
/**
* 显示对象在显示列表上的最终表现出来的透明度,此透明度会继承父级的透明度依次相乘得到最终的值
* @property cAlpha
* @private
* @type {number}
* @since 1.0.0
* @default 1
*/
_this.cAlpha = 1;
_this.isUseToMask = false;
/**
* 显示对象上对显示列表上的最终合成的矩阵,此矩阵会继承父级的显示属性依次相乘得到最终的值
* @property cMatrix
* @private
* @type {annie.Matrix}
* @default null
* @since 1.0.0
*/
_this.cMatrix = new annie.Matrix();
/**
* 因为每次enterFrame事件时都生成一个Event非常浪费资源,所以做成一个全局的
* @property _enterFrameEvent
* @private
* @type {annie.Event}
* @default null
* @since 1.0.0
*/
_this._enterFrameEvent = null;
/**
* 是否可以接受点击事件,如果设置为false,此显示对象将无法接收到点击事件
* @property mouseEnable
* @type {boolean}
* @public
* @since 1.0.0
* @default false
*/
_this.mouseEnable = true;
/**
* 显示对象上对显示列表上的最终的所有滤镜组
* @property cFilters
* @private
* @default []
* @since 1.0.0
* @type {Array}
*/
_this.cFilters = [];
/**
* 每一个显示对象都可以给他启一个名字,这样我们在查找子级的时候就可以直接用this.getChildrndByName("name")获取到这个对象的引用
* @property name
* @since 1.0.0
* @public
* @type {string}
* @default ""
*/
_this.name = "";
_this._x = 0;
_this._y = 0;
_this._scaleX = 1;
_this._scaleY = 1;
_this._rotation = 0;
_this._alpha = 1;
_this._skewX = 0;
_this._skewY = 0;
_this._anchorX = 0;
_this._anchorY = 0;
_this._visible = true;
/**
* 显示对象的混合模式
* 支持的混合模式大概有
* @property blendMode
* @public
* @since 1.0.0
* @type {string}
* @default 0
*/
_this.blendMode = "normal";
_this._matrix = new annie.Matrix();
/**
* 显示对象的遮罩, 是一个Shape显示对象或是一个只包含shape显示对象的MovieClip
* @property mask
* @public
* @since 1.0.0
* @type {annie.DisplayObject}
* @default null
*/
_this.mask = null;
_this._filters = [];
/**
* 是否自己的父级发生的改变
* @type {boolean}
* @private
*/
_this._cp = true;
_this._dragBounds = new annie.Rectangle();
_this._isDragCenter = false;
_this._lastDragPoint = new annie.Point();
/**
* 缓存起来的纹理对象。最后真正送到渲染器去渲染的对象
* @property _texture
* @protected
* @since 1.0.0
* @type {any}
* @default null
*/
_this._texture = null;
/**
* @property _offsetX
* @protected
* @since 1.0.0
* @type {number}
* @default 0
*/
_this._offsetX = 0;
/**
* @property _offsetY
* @protected
* @since 1.0.0
* @type {number}
* @default 0
*/
_this._offsetY = 0;
_this._bounds = new annie.Rectangle();
_this._drawRect = new annie.Rectangle();
_this._instanceType = "annie.DisplayObject";
return _this;
}
Object.defineProperty(DisplayObject.prototype, "x", {
/**
* 显示对象位置x
* @property x
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._x;
},
set: function (value) {
this._setProperty("_x", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "y", {
/**
* 显示对象位置y
* @property y
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._y;
},
set: function (value) {
this._setProperty("_y", value, 0);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(DisplayObject.prototype, "scaleX", {
/**
* 显示对象x方向的缩放值
* @property scaleX
* @public
* @since 1.0.0
* @type {number}
* @default 1
*/
get: function () {
return this._scaleX;
},
set: function (value) {
this._setProperty("_scaleX", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "scaleY", {
/**
* 显示对象y方向的缩放值
* @property scaleY
* @public
* @since 1.0.0
* @type {number}
* @default 1
*/
get: function () {
return this._scaleY;
},
set: function (value) {
this._setProperty("_scaleY", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "rotation", {
/**
* 显示对象旋转角度
* @property rotation
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._rotation;
},
set: function (value) {
this._setProperty("_rotation", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "alpha", {
/**
* 显示对象透明度
* @property alpha
* @public
* @since 1.0.0
* @type {number}
* @default 1
*/
get: function () {
return this._alpha;
},
set: function (value) {
this._setProperty("_alpha", value, 1);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "skewX", {
/**
* 显示对象x方向的斜切值
* @property skewX
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._skewX;
},
set: function (value) {
this._setProperty("_skewX", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "skewY", {
/**
* 显示对象y方向的斜切值
* @property skewY
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._skewY;
},
set: function (value) {
this._setProperty("_skewY", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "anchorX", {
/**
* 显示对象上x方向的缩放或旋转点
* @property anchorX
* @public
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._anchorX;
},
set: function (value) {
this._setProperty("_anchorX", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "anchorY", {
/**
* 显示对象上y方向的缩放或旋转点
* @property anchorY
* @pubic
* @since 1.0.0
* @type {number}
* @default 0
*/
get: function () {
return this._anchorY;
},
set: function (value) {
this._setProperty("_anchorY", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "visible", {
/**
* 显未对象是否可见
* @property visible
* @public
* @since 1.0.0
* @type {boolean}
* @default 0
*/
get: function () { return this._visible; },
set: function (value) {
this._setProperty("_visible", value, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "matrix", {
/**
* 显示对象的变形矩阵
* @property matrix
* @public
* @since 1.0.0
* @type {annie.Matrix}
* @default null
*/
get: function () {
return this._matrix;
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(DisplayObject.prototype, "filters", {
/**
* 显示对象的滤镜数组
* @property filters
* @since 1.0.0
* @public
* @type {Array}
* @default null
*/
get: function () {
return this._filters;
},
set: function (value) {
this._setProperty("_filters", value, 2);
},
enumerable: true,
configurable: true
});
/**
*将全局坐标转换到本地坐标值
* @method globalToLocal
* @since 1.0.0
* @public
* @param {annie.Point} point
* @returns {annie.Point}
*/
DisplayObject.prototype.globalToLocal = function (point, bp) {
if (bp === void 0) { bp = null; }
return this.cMatrix.invert().transformPoint(point.x, point.y, bp);
};
/**
*将本地坐标转换到全局坐标值
* @method localToGlobal
* @public
* @since 1.0.0
* @param {annie.Point} point
* @returns {annie.Point}
*/
DisplayObject.prototype.localToGlobal = function (point, bp) {
if (bp === void 0) { bp = null; }
if (this.parent) {
//下一级的坐标始终应该是相对父级来说的,所以是用父级的矩阵去转换
return this.parent.cMatrix.transformPoint(point.x, point.y, bp);
}
else {
//没有父级
return this.cMatrix.transformPoint(point.x, point.y, bp);
}
};
/**
* 启动鼠标或者触摸拖动
* @method startDrag
* @param {boolean} isCenter 指定将可拖动的对象锁定到指针位置中心 (true),还是锁定到用户第一次单击该对象的位置 (false) 默认false
* @param {annie.Rectangle} bounds 相对于显圣对象父级的坐标的值,用于指定 Sprite 约束矩形
* @since 1.1.2
* @public
*/
DisplayObject.prototype.startDrag = function (isCenter, bounds) {
if (isCenter === void 0) { isCenter = false; }
if (bounds === void 0) { bounds = null; }
var s = this;
if (!s.stage) {
trace("The DisplayObject is not on stage");
return;
}
annie.Stage._dragDisplay = s;
s._isDragCenter = isCenter;
s._lastDragPoint.x = Number.MAX_VALUE;
s._lastDragPoint.y = Number.MAX_VALUE;
if (bounds) {
s._dragBounds.x = bounds.x;
s._dragBounds.y = bounds.y;
s._dragBounds.width = bounds.width;
s._dragBounds.height = bounds.height;
}
else {
s._dragBounds.x = 0;
s._dragBounds.y = 0;
s._dragBounds.width = 0;
s._dragBounds.height = 0;
}
};
/**
* 停止鼠标或者触摸拖动
* @method stopDrag
* @public
* @since 1.1.2
*/
DisplayObject.prototype.stopDrag = function () {
if (annie.Stage._dragDisplay == this) {
annie.Stage._dragDisplay = null;
}
};
/**
* 点击碰撞测试,就是舞台上的一个point是否在显示对象内,在则返回该对象,不在则返回null
* @method hitTestPoint
* @public
* @since 1.0.0
* @param {annie.Point} point 需要碰到的坐标点
* @param {boolean} isMouseEvent 是否是鼠标事件调用此方法,用户一般无须理会,除非你要模拟鼠标点击可以
* @returns {annie.DisplayObject}
*/
DisplayObject.prototype.hitTestPoint = function (point, isMouseEvent) {
if (isMouseEvent === void 0) { isMouseEvent = false; }
var s = this;
if (!s.visible)
return null;
if (isMouseEvent && !s.mouseEnable)
return null;
if (!isMouseEvent) {
//如果不是系统调用则不考虑这个点是从全局来的,只认为这个点就是当前要碰撞测试同级别下的坐标点
if (s.getBounds().isPointIn(point)) {
return s;
}
}
else {
if (s.getBounds().isPointIn(s.globalToLocal(point, DisplayObject._bp))) {
return s;
}
}
return null;
};
/**
* 获取对象的自身的没有任何形变的原始姿态下的原点坐标及宽高,抽像方法
* @method getBounds
* @public
* @since 1.0.0
* @returns {annie.Rectangle}
* @abstract
*/
DisplayObject.prototype.getBounds = function () {
return this._bounds;
};
;
/**
* 获取对象形变后外切矩形。
* 可以从这个方法中读取到此显示对象变形后x方向上的宽和y方向上的高
* @method getDrawRect
* @public
* @since 1.0.0
* @returns {annie.Rectangle}
*/
DisplayObject.prototype.getDrawRect = function () {
var s = this;
var rect = s.getBounds();
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;
}
}
s.matrix.transformPoint(rect.x, rect.y, DisplayObject._p1);
s.matrix.transformPoint(rect.x + rect.width, rect.y, DisplayObject._p2);
s.matrix.transformPoint(rect.x + rect.width, rect.y + rect.height, DisplayObject._p3);
s.matrix.transformPoint(rect.x, rect.y + rect.height, DisplayObject._p4);
annie.Rectangle.createFromPoints(s._drawRect, DisplayObject._p1, DisplayObject._p2, DisplayObject._p3, DisplayObject._p4);
return s._drawRect;
};
/**
* 更新函数
* @method update
* @public
* @param isDrawUpdate 不是因为渲染目的而调用的更新,比如有些时候的强制刷新 默认为true
* @since 1.0.0
*/
DisplayObject.prototype.update = function (isDrawUpdate) {
if (isDrawUpdate === void 0) { isDrawUpdate = false; }
var s = this;
//enterFrame事件一定要放在这里,不要再移到其他地方
if (s.hasEventListener("onEnterFrame")) {
if (!s._enterFrameEvent) {
s._enterFrameEvent = new annie.Event("onEnterFrame");
}
s.dispatchEvent(s._enterFrameEvent);
}
var UI = s._UI;
if (s._cp) {
UI.UM = UI.UA = UI.UF = true;
s._cp = false;
}
if (UI.UM) {
s._matrix.createBox(s._x, s._y, s._scaleX, s._scaleY, s._rotation, s._skewX, s._skewY, s._anchorX, s._anchorY);
}
if (s.parent) {
var PUI = s.parent._UI;
if (PUI.UM)
UI.UM = true;
if (PUI.UA)
UI.UA = true;
if (PUI.UF)
UI.UF = true;
}
if (UI.UM) {
s.cMatrix.setFrom(s._matrix);
if (s.parent) {
s.cMatrix.prepend(s.parent.cMatrix);
}
}
if (UI.UA) {
s.cAlpha = s._alpha;
if (s.parent) {
s.cAlpha *= s.parent.cAlpha;
}
}
if (UI.UF) {
s.cFilters.length = 0;
var sf = s._filters;
if (sf) {
var len = sf.length;
for (var i = 0; i < len; i++) {
s.cFilters.push(sf[i]);
}
}
if (s.parent) {
if (s.parent.cFilters.length > 0) {
var len = s.parent.cFilters.length;
var pf = s.parent.cFilters;
for (var i = len - 1; i >= 0; i--) {
s.cFilters.unshift(pf[i]);
}
}
}
}
};
/**
* 调用此方法将显示对象渲染到屏幕
* @method render
* @public
* @since 1.0.0
* @param {annie.IRender} renderObj
* @abstract
*/
DisplayObject.prototype.render = function (renderObj) {
var s = this;
var cf = s.cFilters;
var cfLen = cf.length;
var fId = -1;
if (cfLen) {
for (var i = 0; i < cfLen; i++) {
if (s.cFilters[i].type == "Shadow") {
fId = i;
break;
}
}
}
if (fId >= 0) {
var ctx = renderObj["_ctx"];
ctx.shadowBlur = cf[fId].blur;
ctx.shadowColor = cf[fId].color;
ctx.shadowOffsetX = cf[fId].offsetX;
ctx.shadowOffsetY = cf[fId].offsetY;
renderObj.draw(s);
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
}
else {
renderObj.draw(s);
}
};
/**
* 调用些方法会冒泡的将事件向显示列表下方传递
* @method _onDispatchBubbledEvent
* @private
* @since 1.0.0
* @param {string} type
* @param {boolean} updateMc 是否更新movieClip时间轴信息
* @private
*/
DisplayObject.prototype._onDispatchBubbledEvent = function (type, updateMc) {
if (updateMc === void 0) { updateMc = false; }
var s = this;
if (type == "onRemoveToStage" && !s.stage)
return;
s.stage = s.parent.stage;
s.dispatchEvent(type);
if (type == "onRemoveToStage") {
s.stage = null;
}
};
Object.defineProperty(DisplayObject.prototype, "width", {
/**
* 获取或者设置显示对象在父级里的x方向的宽,不到必要不要用此属性获取高
* 如果你要同时获取款高,建议使用getWH()方法获取宽和高
* @property width
* @public
* @since 1.0.3
* @return {number}
*/
get: function () {
return this.getWH().width;
},
set: function (value) {
var s = this;
var w = s.width;
if (value > 0 && w > 0) {
var sx = value / w;
s.scaleX *= sx;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(DisplayObject.prototype, "height", {
/**
* 获取或者设置显示对象在父级里的y方向的高,不到必要不要用此属性获取高
* 如果你要同时获取款高,建议使用getWH()方法获取宽和高
* @property height
* @public
* @since 1.0.3
* @return {number}
*/
get: function () {
return this.getWH().height;
},
set: function (value) {
var s = this;
var h = s.height;
if (value > 0 && h > 0) {
var sy = value / h;
s.scaleY *= sy;
}
},
enumerable: true,
configurable: true
});
/**
* 如果需要同时获取宽和高的值,建议使用此方法更有效率
* @method getWH
* @public
* @returns {{width: number, height: number}}
* @since 1.0.9
*/
DisplayObject.prototype.getWH = function () {
var s = this;
s.update();
var dr = s.getDrawRect();
return { width: dr.width, height: dr.height };
};
//protected _isNeedUpdate: boolean = true;
DisplayObject.prototype._setProperty = function (property, value, type) {
var s = this;
if (s[property] != value) {
s[property] = value;
var UI = s._UI;
if (type == 0) {
UI.UM = true;
}
else if (type == 1) {
UI.UA = true;
}
else if (type == 2) {
UI.UF = true;
}
else if (type == 3) {
UI.UD = true;
}
}
};
/**
* 为了hitTestPoint,localToGlobal,globalToLocal等方法不复新不重复生成新的点对象而节约内存
* @type {annie.Point}
* @private
* @static
*/
DisplayObject._bp = new annie.Point();
DisplayObject._p1 = new annie.Point();
DisplayObject._p2 = new annie.Point();
DisplayObject._p3 = new annie.Point();
DisplayObject._p4 = new annie.Point();
/**
* 画缓存位图的时候需要使用
* @property _bitmapCanvas
* @private
* @static
* @since 1.0.0
* @type {Canvas}
*/
DisplayObject._canvas = window.document.createElement("canvas");
return DisplayObject;
}(annie.EventDispatcher));
annie.DisplayObject = DisplayObject;
})(annie || (annie = {}));