travel/admin/node_modules/zrender/lib/Storage.js

232 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
},
/**
* 更新图形的绘制队列。
* 每次绘制前都会调用该方法会先深度优先遍历整个树更新所有Group和Shape的变换并且把所有可见的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) {
// 不指定el清空
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;