var util = require("./core/util"); var env = require("./core/env"); var Group = require("./container/Group"); var timsort = require("./core/timsort"); // Use timsort because in most case elements are partially sorted // https://jsfiddle.net/pissang/jr4x7mdm/8/ function shapeCompareFunc(a, b) { if (a.zlevel === b.zlevel) { if (a.z === b.z) { // if (a.z2 === b.z2) { // // FIXME Slow has renderidx compare // // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement // // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012 // return a.__renderidx - b.__renderidx; // } return a.z2 - b.z2; } return a.z - b.z; } return a.zlevel - b.zlevel; } /** * 鍐呭浠撳簱 (M) * @alias module:zrender/Storage * @constructor */ var Storage = function () { // jshint ignore:line this._roots = []; this._displayList = []; this._displayListLen = 0; }; Storage.prototype = { constructor: Storage, /** * @param {Function} cb * */ traverse: function (cb, context) { for (var i = 0; i < this._roots.length; i++) { this._roots[i].traverse(cb, context); } }, /** * 杩斿洖鎵€鏈夊浘褰㈢殑缁樺埗闃熷垪 * @param {boolean} [update=false] 鏄惁鍦ㄨ繑鍥炲墠鏇存柊璇ユ暟缁� * @param {boolean} [includeIgnore=false] 鏄惁鍖呭惈 ignore 鐨勬暟缁�, 鍦� update 涓� true 鐨勬椂鍊欐湁鏁� * * 璇﹁{@link module:zrender/graphic/Displayable.prototype.updateDisplayList} * @return {Array.<module:zrender/graphic/Displayable>} */ getDisplayList: function (update, includeIgnore) { includeIgnore = includeIgnore || false; if (update) { this.updateDisplayList(includeIgnore); } return this._displayList; }, /** * 鏇存柊鍥惧舰鐨勭粯鍒堕槦鍒椼€� * 姣忔缁樺埗鍓嶉兘浼氳皟鐢紝璇ユ柟娉曚細鍏堟繁搴︿紭鍏堥亶鍘嗘暣涓爲锛屾洿鏂版墍鏈塆roup鍜孲hape鐨勫彉鎹㈠苟涓旀妸鎵€鏈夊彲瑙佺殑Shape淇濆瓨鍒版暟缁勪腑锛� * 鏈€鍚庢牴鎹粯鍒剁殑浼樺厛绾э紙zlevel > z > 鎻掑叆椤哄簭锛夋帓搴忓緱鍒扮粯鍒堕槦鍒� * @param {boolean} [includeIgnore=false] 鏄惁鍖呭惈 ignore 鐨勬暟缁� */ updateDisplayList: function (includeIgnore) { this._displayListLen = 0; var roots = this._roots; var displayList = this._displayList; for (var i = 0, len = roots.length; i < len; i++) { this._updateAndAddDisplayable(roots[i], null, includeIgnore); } displayList.length = this._displayListLen; env.canvasSupported && timsort(displayList, shapeCompareFunc); }, _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) { if (el.ignore && !includeIgnore) { return; } el.beforeUpdate(); if (el.__dirty) { el.update(); } el.afterUpdate(); var userSetClipPath = el.clipPath; if (userSetClipPath) { // FIXME 鏁堢巼褰卞搷 if (clipPaths) { clipPaths = clipPaths.slice(); } else { clipPaths = []; } var currentClipPath = userSetClipPath; var parentClipPath = el; // Recursively add clip path while (currentClipPath) { // clipPath 鐨勫彉鎹㈡槸鍩轰簬浣跨敤杩欎釜 clipPath 鐨勫厓绱� currentClipPath.parent = parentClipPath; currentClipPath.updateTransform(); clipPaths.push(currentClipPath); parentClipPath = currentClipPath; currentClipPath = currentClipPath.clipPath; } } if (el.isGroup) { var children = el._children; for (var i = 0; i < children.length; i++) { var child = children[i]; // Force to mark as dirty if group is dirty // FIXME __dirtyPath ? if (el.__dirty) { child.__dirty = true; } this._updateAndAddDisplayable(child, clipPaths, includeIgnore); } // Mark group clean here el.__dirty = false; } else { el.__clipPaths = clipPaths; this._displayList[this._displayListLen++] = el; } }, /** * 娣诲姞鍥惧舰(Shape)鎴栬€呯粍(Group)鍒版牴鑺傜偣 * @param {module:zrender/Element} el */ addRoot: function (el) { if (el.__storage === this) { return; } if (el instanceof Group) { el.addChildrenToStorage(this); } this.addToStorage(el); this._roots.push(el); }, /** * 鍒犻櫎鎸囧畾鐨勫浘褰�(Shape)鎴栬€呯粍(Group) * @param {string|Array.<string>} [el] 濡傛灉涓虹┖娓呯┖鏁翠釜Storage */ delRoot: function (el) { if (el == null) { // 涓嶆寚瀹歟l娓呯┖ for (var i = 0; i < this._roots.length; i++) { var root = this._roots[i]; if (root instanceof Group) { root.delChildrenFromStorage(this); } } this._roots = []; this._displayList = []; this._displayListLen = 0; return; } if (el instanceof Array) { for (var i = 0, l = el.length; i < l; i++) { this.delRoot(el[i]); } return; } var idx = util.indexOf(this._roots, el); if (idx >= 0) { this.delFromStorage(el); this._roots.splice(idx, 1); if (el instanceof Group) { el.delChildrenFromStorage(this); } } }, addToStorage: function (el) { if (el) { el.__storage = this; el.dirty(false); } return this; }, delFromStorage: function (el) { if (el) { el.__storage = null; } return this; }, /** * 娓呯┖骞朵笖閲婃斁Storage */ dispose: function () { this._renderList = this._roots = null; }, displayableSortFunc: shapeCompareFunc }; var _default = Storage; module.exports = _default;