前言
上一篇文章介绍了如何搭建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(['单击开始绘制,右键取消']);
效果如图所示: