| New file |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2025-04-15 22:41:40 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2025-04-16 19:02:39 |
| | | * @FilePath: \command-center-dashboard\src\hooks\components\useMapHandlerClick.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2025 by shuishen, All Rights Reserved. |
| | | */ |
| | | import * as Cesium from 'cesium' |
| | | import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue' |
| | | |
| | | /** |
| | | * |
| | | * @param {Object} options - 配置选项 |
| | | */ |
| | | export function useMapHandlerClick (viewer, options = { |
| | | type: 'single-drone-event', |
| | | customDom: EventPopUpBox |
| | | }) { |
| | | const { type } = options |
| | | |
| | | const currentClickEntity = ref(null) |
| | | let handler = null |
| | | |
| | | // 查找特定类型的实体 |
| | | const findEntityByType = (entities, type) => { |
| | | return entities.find(entity => |
| | | entity?.properties?.customData?._value?.data?.type === type |
| | | ) |
| | | } |
| | | |
| | | // 左键单机事件 |
| | | const singleMachineEvent = async click => { |
| | | let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id) |
| | | if (!clickedEntities.length) return |
| | | |
| | | currentClickEntity.value = findEntityByType(clickedEntities, type) |
| | | |
| | | removeLabel() |
| | | |
| | | if (currentClickEntity.value) { |
| | | viewer?.scene.postRender.addEventListener(labelBoxRender) |
| | | } |
| | | } |
| | | |
| | | // 事件初始化 |
| | | const handlerInit = () => { |
| | | if (handler) return |
| | | |
| | | handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas) |
| | | handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK) |
| | | } |
| | | |
| | | // 事件移除 |
| | | const removeHandler = () => { |
| | | handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK) |
| | | handler?.destroy() |
| | | handler = null |
| | | } |
| | | |
| | | // 获取弹框box |
| | | const getLabelDom = data => { |
| | | const vNode = h(customDom, { data, removeLabel }) |
| | | const tooltipContainer = document.createElement('div') |
| | | tooltipContainer.id = 'mapPopUpBox' |
| | | tooltipContainer.style.position = 'absolute' |
| | | tooltipContainer.style.transform = styleTransform |
| | | tooltipContainer.style.pointerEvents = 'none' |
| | | document.querySelector('.page-index').append(tooltipContainer) |
| | | render(vNode, tooltipContainer) |
| | | return tooltipContainer |
| | | } |
| | | |
| | | // 弹框位置刷新 |
| | | const labelBoxRender = () => { |
| | | if (!currentEntity) return |
| | | let dom = document.querySelector('#mapPopUpBox') |
| | | if (!dom) { |
| | | dom = getLabelDom(currentEntity.properties.customData._value.data) |
| | | } |
| | | const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value) |
| | | if (screenPosition) { |
| | | dom.style.left = `${screenPosition.x}px` |
| | | dom.style.top = `${screenPosition.y}px` |
| | | dom.style.display = 'block' |
| | | } |
| | | } |
| | | |
| | | const removeDom = () => { |
| | | const dom = document.querySelector('#mapPopUpBox') |
| | | if (dom && dom.parentNode) { |
| | | dom.parentNode.removeChild(dom) |
| | | } |
| | | } |
| | | |
| | | // 移除弹框标签 |
| | | const removeLabel = () => { |
| | | viewer?.scene.postRender.removeEventListener(labelBoxRender) |
| | | removeDom() |
| | | } |
| | | |
| | | // 自动清理 |
| | | onUnmounted(() => { |
| | | removeHandler() |
| | | removeLabel() |
| | | }) |
| | | |
| | | return { |
| | | currentClickEntity, |
| | | handlerInit, |
| | | removeHandler |
| | | } |
| | | } |