| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 | var zrUtil = require("../core/util");var Element = require("../Element");var BoundingRect = require("../core/BoundingRect");/** * Group是一个容器,可以插入子节点,Group的变换也会被应用到子节点上 * @module zrender/graphic/Group * @example *     var Group = require('zrender/container/Group'); *     var Circle = require('zrender/graphic/shape/Circle'); *     var g = new Group(); *     g.position[0] = 100; *     g.position[1] = 100; *     g.add(new Circle({ *         style: { *             x: 100, *             y: 100, *             r: 20, *         } *     })); *     zr.add(g); *//** * @alias module:zrender/graphic/Group * @constructor * @extends module:zrender/mixin/Transformable * @extends module:zrender/mixin/Eventful */var Group = function (opts) {  opts = opts || {};  Element.call(this, opts);  for (var key in opts) {    if (opts.hasOwnProperty(key)) {      this[key] = opts[key];    }  }  this._children = [];  this.__storage = null;  this.__dirty = true;};Group.prototype = {  constructor: Group,  isGroup: true,  /**   * @type {string}   */  type: 'group',  /**   * 所有子孙元素是否响应鼠标事件   * @name module:/zrender/container/Group#silent   * @type {boolean}   * @default false   */  silent: false,  /**   * @return {Array.<module:zrender/Element>}   */  children: function () {    return this._children.slice();  },  /**   * 获取指定 index 的儿子节点   * @param  {number} idx   * @return {module:zrender/Element}   */  childAt: function (idx) {    return this._children[idx];  },  /**   * 获取指定名字的儿子节点   * @param  {string} name   * @return {module:zrender/Element}   */  childOfName: function (name) {    var children = this._children;    for (var i = 0; i < children.length; i++) {      if (children[i].name === name) {        return children[i];      }    }  },  /**   * @return {number}   */  childCount: function () {    return this._children.length;  },  /**   * 添加子节点到最后   * @param {module:zrender/Element} child   */  add: function (child) {    if (child && child !== this && child.parent !== this) {      this._children.push(child);      this._doAdd(child);    }    return this;  },  /**   * 添加子节点在 nextSibling 之前   * @param {module:zrender/Element} child   * @param {module:zrender/Element} nextSibling   */  addBefore: function (child, nextSibling) {    if (child && child !== this && child.parent !== this && nextSibling && nextSibling.parent === this) {      var children = this._children;      var idx = children.indexOf(nextSibling);      if (idx >= 0) {        children.splice(idx, 0, child);        this._doAdd(child);      }    }    return this;  },  _doAdd: function (child) {    if (child.parent) {      child.parent.remove(child);    }    child.parent = this;    var storage = this.__storage;    var zr = this.__zr;    if (storage && storage !== child.__storage) {      storage.addToStorage(child);      if (child instanceof Group) {        child.addChildrenToStorage(storage);      }    }    zr && zr.refresh();  },  /**   * 移除子节点   * @param {module:zrender/Element} child   */  remove: function (child) {    var zr = this.__zr;    var storage = this.__storage;    var children = this._children;    var idx = zrUtil.indexOf(children, child);    if (idx < 0) {      return this;    }    children.splice(idx, 1);    child.parent = null;    if (storage) {      storage.delFromStorage(child);      if (child instanceof Group) {        child.delChildrenFromStorage(storage);      }    }    zr && zr.refresh();    return this;  },  /**   * 移除所有子节点   */  removeAll: function () {    var children = this._children;    var storage = this.__storage;    var child;    var i;    for (i = 0; i < children.length; i++) {      child = children[i];      if (storage) {        storage.delFromStorage(child);        if (child instanceof Group) {          child.delChildrenFromStorage(storage);        }      }      child.parent = null;    }    children.length = 0;    return this;  },  /**   * 遍历所有子节点   * @param  {Function} cb   * @param  {}   context   */  eachChild: function (cb, context) {    var children = this._children;    for (var i = 0; i < children.length; i++) {      var child = children[i];      cb.call(context, child, i);    }    return this;  },  /**   * 深度优先遍历所有子孙节点   * @param  {Function} cb   * @param  {}   context   */  traverse: function (cb, context) {    for (var i = 0; i < this._children.length; i++) {      var child = this._children[i];      cb.call(context, child);      if (child.type === 'group') {        child.traverse(cb, context);      }    }    return this;  },  addChildrenToStorage: function (storage) {    for (var i = 0; i < this._children.length; i++) {      var child = this._children[i];      storage.addToStorage(child);      if (child instanceof Group) {        child.addChildrenToStorage(storage);      }    }  },  delChildrenFromStorage: function (storage) {    for (var i = 0; i < this._children.length; i++) {      var child = this._children[i];      storage.delFromStorage(child);      if (child instanceof Group) {        child.delChildrenFromStorage(storage);      }    }  },  dirty: function () {    this.__dirty = true;    this.__zr && this.__zr.refresh();    return this;  },  /**   * @return {module:zrender/core/BoundingRect}   */  getBoundingRect: function (includeChildren) {    // TODO Caching    var rect = null;    var tmpRect = new BoundingRect(0, 0, 0, 0);    var children = includeChildren || this._children;    var tmpMat = [];    for (var i = 0; i < children.length; i++) {      var child = children[i];      if (child.ignore || child.invisible) {        continue;      }      var childRect = child.getBoundingRect();      var transform = child.getLocalTransform(tmpMat); // TODO      // The boundingRect cacluated by transforming original      // rect may be bigger than the actual bundingRect when rotation      // is used. (Consider a circle rotated aginst its center, where      // the actual boundingRect should be the same as that not be      // rotated.) But we can not find better approach to calculate      // actual boundingRect yet, considering performance.      if (transform) {        tmpRect.copy(childRect);        tmpRect.applyTransform(transform);        rect = rect || tmpRect.clone();        rect.union(tmpRect);      } else {        rect = rect || childRect.clone();        rect.union(childRect);      }    }    return rect || tmpRect;  }};zrUtil.inherits(Group, Element);var _default = Group;module.exports = _default;
 |