AnnieJS API Docs for: 1.1.3
show:

File: libs/DisplayObject.js

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 = {}));