cesium右击事件(判断选中的是否为实体,实体包括billboard、area、point、line、模型等)

303 阅读1分钟

最近有这样一个需求,需要再cesium球上右击触发一个菜单,然后做一些事情,特此记录一下

1.需要加载完一些地球资源才可以注册右击事件

注:vue3封装cesium的一些组件(附网址),viewerRef.value就是封装组件的ref。

onMounted(() => {
  viewerRef.value.creatingPromise.then((readyObj: VcReadyObject) => {  
    let handler = new Cesium.ScreenSpaceEventHandler(globalViewer.value.scene.canvas);
    EventListener_MouseRightClick(handler,globalViewer.value)
  })
})

2.由于功能主要对实体做一些事情,需要判断点击处是否为实体

const EventListener_MouseRightClick = (handler:any,globalViewer:any) => {
    handler.setInputAction(function (evt:any) {
        //设置监听方法
        let scene = globalViewer.scene; //cesium全局对象
        let pick = scene.pick(evt.position);
        // cartesian = scene.pickPosition(evt.position);    // 获取鼠标位置
        // cameraHeight = Math.ceil(viewer.camera.positionCartographic.height);     // 获取相机高度
        if (pick == undefined) {
            console.log("空白处右键");
            //do somethine
        } else {
            console.log("实体处右键,pick);
            // 菜单位置 ----------------- store里面参数如下
            store.showMeau = true  
            store.rightClickMeauData = {
                top:evt.position.y + 'px',
                left:evt.position.x + 'px'
            }
            //do somethine
        }

    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}

3.菜单

<template>
  <teleport to="#app">
    <div v-if="show" class="m" :style="{position: 'fixed',top:pos.top,left:pos.left}">
        <div class="m_item" @click.stop="clickType(item.type)" v-for="(item,i) of eText" :key="i+item.type">{{item.text}}</div>
    </div>
  </teleport>
</template>

<script lang="ts" setup>
import {computed, onMounted,onBeforeUnmount ,ref} from "vue";
import { guidanceStore } from "@/store/guidanceStore";
const store = guidanceStore()
// const props = defineProps({
  // modelValue: {
  //   type: Boolean,
  //   default: false,
  // }
// })
const show = computed(() => store.showMeau)
const pos = computed(() => store.rightClickMeauData)
const eText = ref([
  {
    text: "填写信息",
    type: 'edit'
  },
  {
    text: "展示信息",
    type: 'show',
  }])

const clickType = (type:any) =>{
  console.log(type)
}

onMounted(()=>{
  // 模拟外部点击
  document.addEventListener('click', (e:any) => {
    if (e.target.className !== 'm') {
      store.showMeau = false
    }
  })
})

// 在组件生命周期结束时销毁
onBeforeUnmount(()=>{
    window.removeEventListener('click', () => {}, true)
})

</script>

<style scoped lang="scss">
$l_color: rgba(0, 35, 114, 0.6);
.m {
  background-color: $l_color;
  padding: 8px;
  border: 1px solid #ccc;
  .m_item {
    margin-top: 2px;
    &:hover {
      color: dodgerblue;
    }
  }
}
</style>