UNPKG

@mapgis/webclient-es6-mapboxgl

Version:

477 lines (421 loc) 14.9 kB
import { Common } from '@mapgis/webclient-es6-service'; const { Zondy, indexOf, merge } = Common; import {Group} from './Group'; /** * @private * @class Zondy.LevelRenderer.Storage * @classdesc 内容(图像)仓库 (M) 。 */ class Storage { /** * @function Zondy.LevelRenderer.Storage.constructor * @description 构造函数。 */ constructor() { /** * @member {Object} Zondy.LevelRenderer.Storage.prototype._elements * @description 所有常规形状,id 索引的 map。 */ this._elements = {}; /** * @member {Array} Zondy.LevelRenderer.Storage.prototype._hoverElements * @description 高亮层形状,不稳定,动态增删,数组位置也是 z 轴方向,靠前显示在下方。 * */ this._hoverElements = []; /** * @member {Array} Zondy.LevelRenderer.Storage.prototype._roots * @description _roots。 * */ this._roots = []; /** * @member {Array} Zondy.LevelRenderer.Storage.prototype._shapeList * @description _shapeList。 * */ this._shapeList = []; /** * @member {number} Zondy.LevelRenderer.Storage.prototype._shapeListOffset * @description _shapeListOffset。默认值:0。 * */ this._shapeListOffset = 0; this.CLASS_NAME = "Zondy.LevelRenderer.Storage"; } /** * @function Zondy.LevelRenderer.Storage.prototype.destroy * @description 销毁对象,释放资源。调用此函数后所有属性将被置为 null。 */ destroy() { this.dispose(); this._shapeList = null; this._shapeListOffset = null; } /** * @function Zondy.LevelRenderer.Storage.prototype.iterShape * @description 遍历迭代器。 * * @param {Function} fun - 迭代回调函数,return true终止迭代。 * @param {Object} option - 迭代参数,缺省为仅降序遍历普通层图形。 * @param {boolean} [hover=true] - 是否是高亮层图形。 * @param {string} [normal='down'] - 是否是普通层图形,迭代时是否指定及z轴顺序。可设值:'down' ,'up'。 * @param {boolean} [update=false] - 是否在迭代前更新形状列表。 * @return {Zondy.LevelRenderer.Storage} this。 */ iterShape(fun, option) { if (!option) { var defaultIterateOption = { hover: false, normal: 'down', update: false }; option = defaultIterateOption; } if (option.hover) { // 高亮层数据遍历 for (var i = 0, l = this._hoverElements.length; i < l; i++) { var el = this._hoverElements[i]; el.updateTransform(); if (fun(el)) { return this; } } } if (option.update) { this.updateShapeList(); } // 遍历: 'down' | 'up' switch (option.normal) { case 'down': { // 降序遍历,高层优先 let l = this._shapeList.length; while (l--) { if (fun(this._shapeList[l])) { return this; } } break; } // case 'up': default: { // 升序遍历,底层优先 for (let i = 0, l = this._shapeList.length; i < l; i++) { if (fun(this._shapeList[i])) { return this; } } break; } } return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.getHoverShapes * @param {boolean} [update=false] - 是否在返回前更新图形的变换。 * @return {Array.<Zondy.LevelRenderer.Shape>} 图形数组。 */ getHoverShapes(update) { // hoverConnect var hoverElements = [], len = this._hoverElements.length; for (let i = 0; i < len; i++) { hoverElements.push(this._hoverElements[i]); var target = this._hoverElements[i].hoverConnect; if (target) { var shape; target = target instanceof Array ? target : [target]; for (var j = 0, k = target.length; j < k; j++) { shape = target[j].id ? target[j] : this.get(target[j]); if (shape) { hoverElements.push(shape); } } } } hoverElements.sort(Storage.shapeCompareFunc); if (update) { for (let i = 0, l = hoverElements.length; i < l; i++) { hoverElements[i].updateTransform(); } } return hoverElements; } /** * @function Zondy.LevelRenderer.Storage.prototype.getShapeList * @description 返回所有图形的绘制队列。 * * @param {boolean} [update=false] - 是否在返回前更新该数组。 详见:<Zondy.LevelRenderer.Shape> updateShapeList。 * @return {Zondy.LevelRenderer.Shape} 图形。 */ getShapeList(update) { if (update) { this.updateShapeList(); } return this._shapeList; } /** * @function Zondy.LevelRenderer.Storage.prototype.updateShapeList * @description 更新图形的绘制队列。每次绘制前都会调用,该方法会先深度优先遍历整个树,更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中,最后根据绘制的优先级(zlevel > z > 插入顺序)排序得到绘制队列。 */ updateShapeList() { this._shapeListOffset = 0; var rootsLen = this._roots.length; for (let i = 0; i < rootsLen; i++) { let root = this._roots[i]; this._updateAndAddShape(root); } this._shapeList.length = this._shapeListOffset; var shapeListLen = this._shapeList.length; for (let i = 0; i < shapeListLen; i++) { this._shapeList[i].__renderidx = i; } this._shapeList.sort(Storage.shapeCompareFunc); } /** * @function Zondy.LevelRenderer.Storage.prototype._updateAndAddShape * @description 更新并添加图形。 */ _updateAndAddShape(el, clipShapes) { if (el.ignore) { return; } el.updateTransform(); if (el.type === 'group') { if (el.clipShape) { // clipShape 的变换是基于 group 的变换 el.clipShape.parent = el; el.clipShape.updateTransform(); // PENDING 效率影响 if (clipShapes) { clipShapes = clipShapes.slice(); clipShapes.push(el.clipShape); } else { clipShapes = [el.clipShape]; } } for (var i = 0; i < el._children.length; i++) { var child = el._children[i]; // Force to mark as dirty if group is dirty child.__dirty = el.__dirty || child.__dirty; this._updateAndAddShape(child, clipShapes); } // Mark group clean here el.__dirty = false; } else { el.__clipShapes = clipShapes; this._shapeList[this._shapeListOffset++] = el; } } /** * @function Zondy.LevelRenderer.Storage.prototype.mod * @description 修改图形(Shape)或者组(Group)。 * * @param {string} elId - 唯一标识。 * @param {Object} params - 参数。 * @return {Zondy.LevelRenderer.Storage} this。 */ mod(elId, params) { var el = this._elements[elId]; if (el) { el.modSelf(); if (params) { // 如果第二个参数直接使用 shape // parent, _storage, __startClip 三个属性会有循环引用 if (params.parent || params._storage || params.__startClip) { var target = {}; for (var name in params) { if ( name === 'parent' || name === '_storage' || name === '__startClip' ) { continue; } if (params.hasOwnProperty(name)) { target[name] = params[name]; } } merge(el, target, true); } else { merge(el, params, true); } } } return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.drift * @description 移动指定的图形(Shape)的位置。 * @param {string} shapeId - 唯一标识。 * @param {number} dx * @param {number} dy * @return {Zondy.LevelRenderer.Storage} this。 */ drift(shapeId, dx, dy) { var shape = this._elements[shapeId]; if (shape) { shape.needTransform = true; if (shape.draggable === 'horizontal') { dy = 0; } else if (shape.draggable === 'vertical') { dx = 0; } if (!shape.ondrift // ondrift // 有onbrush并且调用执行返回false或undefined则继续 || (shape.ondrift && !shape.ondrift(dx, dy)) ) { shape.drift(dx, dy); } } return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.addHover * @description 添加高亮层数据。 * @param {Zondy.LevelRenderer.Shape} shape - 图形。 * @return {Zondy.LevelRenderer.Storage} this。 */ addHover(shape) { shape.updateNeedTransform(); this._hoverElements.push(shape); return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.delHover * @description 清空高亮层数据。 * @return {Zondy.LevelRenderer.Storage} this。 */ delHover() { this._hoverElements = []; return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.hasHoverShape * @description 是否有图形在高亮层里。 * @return {boolean} 是否有图形在高亮层里。 */ hasHoverShape() { return this._hoverElements.length > 0; } /** * @function Zondy.LevelRenderer.Storage.prototype.addRoot * @description 添加图形(Shape)或者组(Group)到根节点。 * * @param {(Zondy.LevelRenderer.Shape/Zondy.LevelRenderer.Group)} el - 图形。 * */ addRoot(el) { if (el instanceof Group) { el.addChildrenToStorage(this); } this.addToMap(el); this._roots.push(el); } /** * @function Zondy.LevelRenderer.Storage.prototype.delRoot * @description 删除指定的图形(Shape)或者组(Group)。 * * @param {Array.<string>} elId - 删除图形(Shape)或者组(Group)的 id 数组。如果为空清空整个Storage。 * */ delRoot(elId) { if (typeof (elId) == 'undefined') { // 不指定elId清空 for (var i = 0; i < this._roots.length; i++) { var root = this._roots[i]; if (root instanceof Group) { root.delChildrenFromStorage(this); } } this._elements = {}; this._hoverElements = []; this._roots = []; return; } if (elId instanceof Array) { var elIdLen = elId.length; for (let i = 0; i < elIdLen; i++) { this.delRoot(elId[i]); } return; } var el; if (typeof (elId) == 'string') { el = this._elements[elId]; } else { el = elId; } var idx = indexOf(this._roots, el); if (idx >= 0) { this.delFromMap(el.id); this._roots.splice(idx, 1); if (el instanceof Group) { el.delChildrenFromStorage(this); } } } /** * @function Zondy.LevelRenderer.Storage.prototype.addToMap * @description 添加图形到 map。 * * @param {Zondy.LevelRenderer.Shape} el - 图形。 * @return {Zondy.LevelRenderer.Storage} this。 */ addToMap(el) { if (el instanceof Group) { el._storage = this; } el.modSelf(); this._elements[el.id] = el; return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.get * @description 获取指定图形。 * * @param {string} elId - 图形 id。 * @return {Zondy.LevelRenderer.Shape} 图形。 */ get(elId) { return this._elements[elId]; } /** * @function Zondy.LevelRenderer.Storage.prototype.delFromMap * @description 从 map 中删除指定图形。 * * @param {string} elId - 图形id。 * @return {Zondy.LevelRenderer.Storage} this。 */ delFromMap(elId) { var el = this._elements[elId]; if (el) { delete this._elements[elId]; if (el instanceof Group) { el._storage = null; } } return this; } /** * @function Zondy.LevelRenderer.Storage.prototype.dispose * @description 清空并且释放 Storage。 */ dispose() { this._elements = null; // this._renderList = null; this._roots = null; this._hoverElements = null; } static shapeCompareFunc(a, b) { if (a.zlevel === b.zlevel) { if (a.z === b.z) { return a.__renderidx - b.__renderidx; } return a.z - b.z; } return a.zlevel - b.zlevel; } } export {Storage}; Zondy.LevelRenderer.Storage = Storage;