UNPKG

@cesium-extends/subscriber

Version:

该包提供了一种方便的方式,用于在 Cesium 场景中订阅事件。它允许您为指定的实体添加事件监听器,并在发生事件时触发回调函数。

204 lines (201 loc) 6.16 kB
import { ScreenSpaceEventHandler, ScreenSpaceEventType } from 'cesium'; function uniqueId() { let _val = ""; do { _val = Math.random().toString(36).slice(-8); } while (_val.length < 8); return _val; } class Subscriber { _viewer; _handler; _eventCollection = /* @__PURE__ */ Object.create(null); _externalEventCollection = /* @__PURE__ */ Object.create({}); _eventTypeList = [ "LEFT_DOWN", "LEFT_UP", "LEFT_CLICK", "LEFT_DOUBLE_CLICK", "RIGHT_DOWN", "RIGHT_UP", "RIGHT_CLICK", "MIDDLE_DOWN", "MIDDLE_UP", "MIDDLE_CLICK", "MOUSE_MOVE", "WHEEL", "PINCH_START", "PINCH_MOVE", "PINCH_END" ]; _moveDebounce; _lastTime; _enablePickResult; _lastResult; _enable = true; _isDestroy; /** * 是否被销毁 */ get isDestroy() { return this._isDestroy; } /** 是否执行监听回调 */ get enable() { return this._enable; } set enable(val) { this._enable = val; } constructor(viewer, options = {}) { var _a, _b; this._viewer = viewer; this._handler = new ScreenSpaceEventHandler( options.element || this._viewer.canvas ); this._moveDebounce = (_a = options.pickResult) == null ? void 0 : _a.moveDebounce; this._enablePickResult = ((_b = options.pickResult) == null ? void 0 : _b.enable) ?? false; this._lastTime = (/* @__PURE__ */ new Date()).getTime(); this._isDestroy = false; this._initListener(); } _initListener() { this._eventTypeList.forEach((type) => { this._eventCollection[type] = /* @__PURE__ */ new Map(); this._externalEventCollection[type] = /* @__PURE__ */ new Map(); }); } _shouldUpdate(update = true) { if (!this._moveDebounce) return true; const timeNow = (/* @__PURE__ */ new Date()).getTime(); if (timeNow - this._lastTime < this._moveDebounce) { return false; } else { if (update) this._lastTime = timeNow; return true; } } _eventRegister(eventType) { if (this._isDestroy) return; const eventCollection = this._eventCollection[eventType]; const externalEventCollection = this._externalEventCollection[eventType]; this._handler.setInputAction((movement) => { var _a; if (this._isDestroy || !this._enable || eventType === "MOUSE_MOVE" && !this._shouldUpdate()) return; if (this._enablePickResult) { if (eventType === "MOUSE_MOVE" && movement.endPosition) { this._lastResult = this._viewer.scene.pick(movement.endPosition); } else if (movement.position) { this._lastResult = this._viewer.scene.pick(movement.position); } } if (externalEventCollection.size > 0) { const iterator = externalEventCollection.values(); let val = iterator.next(); while (!val.done) { val.value(movement, this._lastResult); val = iterator.next(); } } if (movement.position || movement.endPosition) { const entity = (_a = this._lastResult) == null ? void 0 : _a.id; if (entity && eventCollection.has(entity.id) && typeof eventCollection.get(entity.id) === "function") { const func = eventCollection.get(entity.id); if (func) func(movement, entity); } } }, ScreenSpaceEventType[eventType]); } /** * @description 为Entity添加监听事件 * * @event * * @param {Function} callback 需要相应的事件 * * @param {EventType} eventType 事件类型 */ add(substances, callback, eventType) { if (this._isDestroy) return; if (this._eventCollection[eventType].size === 0 && this._externalEventCollection[eventType].size === 0) this._eventRegister(eventType); const substancesArray = Array.isArray(substances) ? substances : [substances]; for (const substance of substancesArray) { this._eventCollection[eventType].set(substance.id, callback); } } /** * @description 添加特定事件,与add不同在于该事件不会过滤Entity * @param callback 事件处理函数 * @param eventType 事件类型 * @return {string} Event Id 事件移除时需要提供事件ID */ addExternal(callback, eventType) { if (this._isDestroy) return ""; if (this._eventCollection[eventType].size === 0 && this._externalEventCollection[eventType].size === 0) this._eventRegister(eventType); const eId = uniqueId(); this._externalEventCollection[eventType].set(eId, callback); return eId; } /** *@description 移除指定Substance的相应事件 * @param substances 需要移除事件的Substance * @param eventType 需要移除的时间类型 */ remove(substances, eventType) { if (this._isDestroy) return; const substancesArray = Array.isArray(substances) ? substances : [substances]; for (const substance of substancesArray) { if (this._eventCollection[eventType].has(substance.id)) { this._eventCollection[eventType].delete(substance.id); } } } removeExternal(ids, eventType) { var _a; if (this._isDestroy) return; const idsArray = Array.isArray(ids) ? ids : [ids]; for (const id of idsArray) { const type = eventType || this._searchExternal(id); if (type && ((_a = this._externalEventCollection[type]) == null ? void 0 : _a.has(id))) { this._externalEventCollection[type].delete(id); } } } _searchExternal(id) { if (this._isDestroy) return; const types = Object.keys( this._externalEventCollection ); for (const type of types) { const events = this._externalEventCollection[type]; if (events.has(id)) return type; } return; } removeNative(viewer, eventType) { viewer.screenSpaceEventHandler.removeInputAction( this.convertCesiumEventType(eventType) ); } convertCesiumEventType(subscriberEventType) { return ScreenSpaceEventType[subscriberEventType]; } destroy() { this._isDestroy = true; this._handler.destroy(); } } export { Subscriber, Subscriber as default };