3dpopup弹框修改

This commit is contained in:
扈兆增 2026-07-14 17:18:30 +08:00
parent 72d91355bb
commit abfa77f645

View File

@ -13,6 +13,7 @@ export class MapCesium implements MapInterface {
private clickEventHandler: Cesium.ScreenSpaceEventHandler | null = null;
private popupElement: HTMLElement | null = null;
private hoveredEntityId: string | null = null;
private hoverRafId: number | null = null; // requestAnimationFrame 节流
private removePostRenderListener: (() => void) | null = null;
private isBatchPopupMode = false;
private batchPopupContainer: HTMLDivElement | null = null;
@ -266,53 +267,65 @@ export class MapCesium implements MapInterface {
// 默认箭头光标,与 2D 一致(不显示拖拽小手)
canvas.style.cursor = 'default';
// 鼠标移动:光标样式 + hover popup批量模式下只改光标
// 鼠标移动:光标样式 + hover popuprAF 节流,批量模式下只改光标)
let pendingMoveEvent: { endPosition: Cesium.Cartesian2 } | null = null;
this.clickEventHandler.setInputAction(
(move: { endPosition: Cesium.Cartesian2 }) => {
const scene = this.viewer?.scene;
if (!scene) return;
pendingMoveEvent = move;
const cameraHeight = this.getCurrentCameraHeight();
// 缩放门槛:中国视角以上不触发 hover
if (cameraHeight > this.HOVER_POPUP_MAX_HEIGHT) {
canvas.style.cursor = 'default';
this.hidePopup();
return;
}
if (this.hoverRafId !== null) return; // 已有待处理的帧,跳过
this.hoverRafId = requestAnimationFrame(() => {
this.hoverRafId = null;
const evt = pendingMoveEvent;
pendingMoveEvent = null;
if (!evt) return;
const picked = scene.pick(move.endPosition);
const entity =
Cesium.defined(picked) && picked.id instanceof Cesium.Entity
? (picked.id as Cesium.Entity)
: null;
const scene = this.viewer?.scene;
if (!scene) return;
// 检测是否命中可交互的锚点
if (entity && this.isEntityInteractive(entity)) {
canvas.style.cursor = 'pointer';
// 批量模式下单点 hover 不触发 popup
if (this.isBatchPopupMode) return;
// 同一个实体不重复刷新
if (this.hoveredEntityId === entity.id) {
const position = entity.position?.getValue(
this.viewer!.clock.currentTime
);
if (position) {
this.updatePopupPosition(position);
}
const cameraHeight = this.getCurrentCameraHeight();
// 缩放门槛:中国视角以上不触发 hover
if (cameraHeight > this.HOVER_POPUP_MAX_HEIGHT) {
canvas.style.cursor = 'default';
this.hidePopup();
return;
}
this.showPopupForEntity(entity);
return;
}
const picked = scene.pick(evt.endPosition);
const entity =
Cesium.defined(picked) && picked.id instanceof Cesium.Entity
? (picked.id as Cesium.Entity)
: null;
canvas.style.cursor = 'default';
// 批量模式下不隐藏批量 popup
if (!this.isBatchPopupMode) {
this.hidePopup();
}
// 检测是否命中可交互的锚点
if (entity && this.isEntityInteractive(entity)) {
canvas.style.cursor = 'pointer';
// 批量模式下单点 hover 不触发 popup
if (this.isBatchPopupMode) return;
// 同一个实体不重复刷新
if (this.hoveredEntityId === entity.id) {
const position = entity.position?.getValue(
this.viewer!.clock.currentTime
);
if (position) {
this.updatePopupPosition(position);
}
return;
}
this.showPopupForEntity(entity);
return;
}
canvas.style.cursor = 'default';
// 批量模式下不隐藏批量 popup
if (!this.isBatchPopupMode) {
this.hidePopup();
}
});
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
@ -337,7 +350,7 @@ export class MapCesium implements MapInterface {
} else {
modelStore.modalVisible = true;
modelStore.params = rawData;
modelStore.title = (rawData.titleName || rawData.stnm) + ' 详情信息';
modelStore.title = rawData.titleName || rawData.stnm;
}
},
Cesium.ScreenSpaceEventType.LEFT_CLICK
@ -614,7 +627,8 @@ export class MapCesium implements MapInterface {
const { entity, x, y, popupHtml } = candidates[i];
const popupEl = document.createElement('div');
popupEl.className = 'map-popup-container';
popupEl.className =
this.popupElement?.className || 'map-popup-container';
popupEl.innerHTML = popupHtml;
popupEl.style.position = 'absolute';
popupEl.style.display = 'block';
@ -1077,10 +1091,19 @@ export class MapCesium implements MapInterface {
initPopupOverlay(popupContainer: HTMLDivElement): void {
this.popupElement = popupContainer;
if (this.popupElement) {
// 清除可能残留的旧样式
this.popupElement.style.removeProperty('position');
this.popupElement.style.removeProperty('transform');
this.popupElement.style.removeProperty('left');
this.popupElement.style.removeProperty('top');
this.popupElement.style.display = 'none';
this.popupElement.style.position = 'absolute';
this.popupElement.style.transform = 'translate(-50%, calc(-100% - 10px))';
this.popupElement.style.pointerEvents = 'none';
this.popupElement.style.setProperty(
'pointer-events',
'none',
'important'
);
}
}