cesium 鼠标提示语功能实现


前言

上一篇文章介绍了如何搭建cesium+vue2.x的项目环境,这一篇主要介绍如何在搭建好的项目环境中,实现在Cesium的地图上生成鼠标提示语


想要在绘制的过程中,实时的出现绘制提示,思路如下:

1.建立提示文字组件

新建一个.vue的组件,名字随意,我这里叫cesiumTips.vue,作用是显示绘制时的提示文字,代码如下:

<template>
    <div id="cesiumTips" v-show="showTips">
        <div id="triangle-left" v-show="tipArray.length>0"></div>
        <p v-for="item in tipArray"><span>{{item}}</span></p>
    </div>
</template>

<script lang="ts">
    import {Component, Vue} from 'vue-property-decorator';
    import MRzhGlobalListener from "./MRzhGlobalListener";
    @Component({
        components: {

        },
    })
    export default class cesiumTips extends Vue {
        tipArray:any=[];
        showTips:boolean=false;
        mounted(): void {
            let tipsDom=document.getElementById('cesiumTips');
            MRzhGlobalListener.getInstance().setTipDom(tipsDom);
            MRzhGlobalListener.getInstance().setTipsCallback(this.tipsCallback)
        }
        tipsCallback(tipArray:any,showTips:boolean=true){
            this.showTips=showTips;
            this.tipArray=JSON.parse(JSON.stringify(tipArray));
        }
    }
</script>

<style lang="less">

    #cesiumTips{
        position: absolute;
        background: rgba(0,0,0,0.7);
        padding:5px 10px;
        left: 20px;
        z-index: 100000;
        pointer-events: none;
        border-radius: 7px;
        p{
            text-align: center;
            color: white;
            line-height: 20px;
            font-size: 14px;
        }
        #triangle-left {
            width: 0;
            height: 0;
            position: absolute;
            top: 50%;
            left: -10px;
            margin-top: -5px;
            border-top: 5px solid transparent;
            border-right: 10px solid rgba(0,0,0,0.7);
            border-bottom: 5px solid transparent;
        }
    }
</style>

2.实现提示语的类MRzhGlobalListener

思路是:通过实时监听鼠标在地球上的移动,将提示组件位置跟随鼠标,并且设计可以实时修改提示文字的接口,这里我定义了一个MRzhGlobalListener的类来实现,将这个类放在和cesiumTips 的同级目录下,代码如下:

 import CesiumByZh from "../CesiumByZh"; //这里的CesiumByZh类我就不在写了,请参看https://blog.csdn.net/weixin_43812586/article/details/126172462

export default class MRzhGlobalListener{
	public canvas = CesiumByZh.viewer.scene.canvas;
    public camera = CesiumByZh.viewer.scene.camera;
    public ellipsoid = CesiumByZh.viewer.scene.globe.ellipsoid;
    public viewer = CesiumByZh.viewer;
    public scene = CesiumByZh.viewer.scene;
    private handler: any = new CesiumByZh.Cesium.ScreenSpaceEventHandler(this.canvas);
    private static _instance: rtwsGlobalListener;
    private tipsCallback: any;//提示语的回调函数
    private tipsDom: any;

    static getInstance() {
        if (MRzhGlobalListener._instance == null) {
            MRzhGlobalListener._instance = new MRzhGlobalListener();
        }
        return MRzhGlobalListener._instance;
    }

    setTipDom(tipsDom: any) {
        this.tipsDom = tipsDom;
    }

    setTipsCallback(callback: any) {
        this.tipsCallback = callback;
    }
    runTipsCallback(tipArray:any,showTips:boolean=true){
        this.tipsCallback(tipArray,showTips)
    }

    leftClickListener() {
        this.handler.setInputAction((event: any) => {
            let position = event.position;
            if (!CesiumByZh.Cesium.defined(position)) {
                return;
            }
            let ray = this.camera.getPickRay(position);
            if (!CesiumByZh.Cesium.defined(ray)) {
                return;
            }
            let cartesian = this.scene.globe.pick(ray, this.scene);
            if (!CesiumByZh.Cesium.defined(cartesian)) {
                return;
            }
            let pick = CesiumByZh.viewer.scene.pick(position);
        }, CesiumByZh.Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }

    rightClickListener() {
        this.handler.setInputAction((event: any) => {
            let position = event.position;
            if (!CesiumByZh.Cesium.defined(position)) {
                return;
            }
            let ray = this.camera.getPickRay(position);
            if (!CesiumByZh.Cesium.defined(ray)) {
                return;
            }
            let cartesian = this.scene.globe.pick(ray, this.scene);
            if (!CesiumByZh.Cesium.defined(cartesian)) {
                return;
            }
            let pick = CesiumByZh.viewer.scene.pick(position);
            
        }, CesiumByZh.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }

    mousemoveListener() {
        this.handler.setInputAction((event: any) => {
            let position = event.endPosition;
            if (!CesiumByZh.Cesium.defined(position)) {
                return;
            }
            let ray = this.camera.getPickRay(position);
            if (!CesiumByZh.Cesium.defined(ray)) {
                return;
            }
            let cartesian = this.scene.globe.pick(ray, this.scene);
            if (!CesiumByZh.Cesium.defined(cartesian)) {
                return;
            }
            if (this.tipsDom != null) {
                this.mouseMoveTipsFollow(cartesian);
            }
        }, CesiumByZh.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }

    //鼠标移动,提示语窗体跟随
    mouseMoveTipsFollow(cartesian: any) {
        let divposition = CesiumByZh.Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.scene, cartesian);
        if (divposition) {
            this.tipsDom.style.left = divposition.x + 10 + 'px';
            this.tipsDom.style.top = divposition.y - this.tipsDom.offsetHeight / 2 + 'px';
        } else {
            this.tipsDom.style.left = -1000 + 'px';
            this.tipsDom.style.top = 0 + 'px';
        }
    }
}

3.使用MRzhGlobalListener的方式

首先将第一步创建的cesiumTips.vue引入到app.vue当中,这一步我就不写代码了,然后在CesiumByZh这个类的当中添加如下代码

/*CesiumByZh.viewer.scene.screenSpaceCameraController.tiltEventTypes = [CesiumByZh.Cesium.CameraEventType.MIDDLE_DRAG, CesiumByZh.Cesium.CameraEventType.PINCH];
if (funhander != null) {
     // @ts-ignore
     funhander();
 }*/
 //前面的都是CesiumByZh已有的代码
MRzhGlobalListener.getInstance().mousemoveListener();//这里是开启提示语的移动监听

然后当你需要地图上出现提示语时,就调用MRzhGlobalListener这个类下面的runTipsCallback函数,传入对应的提示文字即可,这个函数支持传入一个数组,举例:

MRzhGlobalListener.getInstance().runTipsCallback(['单击开始绘制,右键取消']);

效果如图所示:
在这里插入图片描述

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sannianerban12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值