AnnieJS API Docs for: 1.1.3
show:

File: libs/Sprite.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) {
    /**
     * 显示对象的容器类,可以将其他显示对象放入其中,是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 = {}));