@cesium-extends/subscriber
Version:
该包提供了一种方便的方式,用于在 Cesium 场景中订阅事件。它允许您为指定的实体添加事件监听器,并在发生事件时触发回调函数。
204 lines (201 loc) • 6.16 kB
JavaScript
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 };