文章目录
- 问题
- 分析
问题
在开发中,遇到这么一种情况,鼠标移动生成坐标点的经纬,因此 lable 是根据鼠标移动一起的,但是当鼠标脱离球体之后,最后一次在球上的标签依然还固定在球上未被消除,想过用删除实体的方式删除,但并没有用。因此,经过尝试之后总结如下:
分析
要实现鼠标在球体上显示,离开球体不显示的效果,你可以借助 Cesium 的 Entity 对象和 ScreenSpaceEventHandler 来实现。首先,创建一个球体的 Entity 对象,然后在鼠标移动事件中更新球体的可见性。
以下是一个示例代码:
// 创建 Cesium 场景
var viewer = new Cesium.Viewer('cesiumContainer');// 创建球体的 Entity 对象
var sphere = viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),ellipsoid: {radii: new Cesium.Cartesian3(500000.0, 500000.0, 500000.0),fill: true,outline: true,outlineColor: Cesium.Color.BLACK,material: Cesium.Color.RED.withAlpha(0.5)},show: false // 初始状态下不显示球体
});// 创建 ScreenSpaceEventHandler 对象
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);// 监听鼠标移动事件
handler.setInputAction(function(movement) {var position = movement.endPosition;// 将屏幕坐标转换为世界坐标var ray = viewer.camera.getPickRay(position);var intersection = viewer.scene.globe.pick(ray, viewer.scene);if (Cesium.defined(intersection)) {// 鼠标在球上移动时,显示球体sphere.show = true;} else {// 鼠标离开球时,隐藏球体sphere.show = false;}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
在上述代码中,我们创建了一个 Cesium 场景 viewer。然后,我们创建了一个球体的 Entity 对象 sphere,并设置其初始位置和外观属性。初始状态下,将 sphere.show 设置为 false 来隐藏球体。
然后,我们创建了一个 ScreenSpaceEventHandler 对象 handler,并使用 setInputAction 方法监听鼠标移动事件。当鼠标移动时,会触发回调函数,其中 movement.endPosition 是鼠标在屏幕上的位置。
我们使用 viewer.camera.getPickRay(position) 将屏幕坐标转换为射线。然后,通过 viewer.scene.globe.pick(ray, viewer.scene) 方法,判断射线是否与球体交叉。如果有交叉点,则说明鼠标在球体上移动,将 sphere.show 设置为 true 来显示球体;如果没有交叉点,则说明鼠标离开球体,将 sphere.show 设置为 false 来隐藏球体。
经过上述的案例思考后,想出可以使用 this.viewer.entities.remove(labelEntity);
来删除
接下来是我完整代码:
- 鼠标移动事件
//鼠标移动事件
mouseMoveEvent() {var labelEntity = null; // 标签实体this.viewer.screenSpaceEventHandler.setInputAction((moveEvent) => {//var movePosition = this.viewer.scene.pickPosition(moveEvent.endPosition); // 鼠标移动的点// 判断是否在球上var movePosition = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(moveEvent.endPosition), this.viewer.scene);if(movePosition){this.leafEath = true;console.log(movePosition)if (this.positions.length == 2) {this.positions.pop();this.positions.push(movePosition);// 绘制labelif (labelEntity) {this.viewer.entities.remove(labelEntity);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity), 1);}// 计算中点this.centerPoint = Cesium.Cartesian3.midpoint(this.positions[0], this.positions[1], new Cesium.Cartesian3());// 计算距离this.lengthText = "距离:" + this.getLengthText(this.positions[0], this.positions[1]);// 鼠标移动事件labelEntity = this.addLabel(this.centerPoint, this.lengthText);this.entityCollection.push(labelEntity);} else {this.positions.push(movePosition);}}else{this.leafEath = false;// 用于控制点击后生成的坐标标签信息,因为之前鼠标点击后要生成坐标标签,因此这个时候需要也控制一下this.viewer.entities.remove(labelEntity);return false;}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);},
- 添加标签
// 添加标签
addLabel(centerPosition, text) {return this.viewer.entities.add(new Cesium.Entity({position: centerPosition,label: {text: text,font: '14px sans-serif',style: Cesium.LabelStyle.FILL_AND_OUTLINE, //FILL FILL_AND_OUTLINE OUTLINEfillColor: Cesium.Color.YELLOW,showBackground: true, //指定标签后面背景的可见性backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 背景颜色backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充paddingpixelOffset: new Cesium.Cartesian2(0, -25),disableDepthTestDistance: Number.POSITIVE_INFINITY}}));
},