cesium添加弹窗,跟随实体移动

先看效果,弹窗会跟随实体移动

1、首先我们先写一个弹窗样式,如果是vue开发,css最好写到公共引入的css ,组件内css会编译后会加hash值

2、然后我们 开启 cesium的监听事件, 注意的是  initBubbleWindow方法在地球加载后再调用

 const initBubbleWindow = () => {
    let scene = viewer.scene,
        camera = viewer.camera,
        handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

    handler.setInputAction((movement) => {
        if (viewer.selectedEntity) {
            // 获取实体id  如果是不同实体  可以在这里过滤
            let selectID = viewer.selectedEntity.id
                console.log(selectID)
            // 创建弹窗前先关闭 之前的弹窗  如果你要展示多个弹窗 这里可以不用调用
            orb.deletePopup()
            orb.popupWindow(selectID);
           
        } else {
            // 如果你点的不是实体 是空白区域 弹窗销毁  如果你有统一销毁的方法 这里也可以省略
            orb.deletePopup()
        }

    }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 监听左键
};

3、通过左键获取到 实体id后 我们拿到实体的数据,然后进行显示


     // 气泡弹窗
    popupWindow(id) {
        // 先创建元素
        let domId = "popupwin-" + id // 多个弹窗id不一样
        let html = window.document.createElement("div");
        html.className = "popupwin"; // 这里就是我们一开始写样式的弹窗 
        html.id = domId
     
        document.body.appendChild(html);

        let scene, camera
        let helper = new window.Cesium.EventHelper();
        let that = this 
        // 这里写一个函数 用cesium的计时器 定时调用,这也是 弹窗可以跟着实体移动的主要方式
        function listenersfunc() {
            scene = viewer.scene;
            camera = viewer.camera;
            if (
                viewer.entities &&
                viewer.entities.getById(id)
            ) {
                // 根据实体id获取实体id的位置坐标
                let cartesian = viewer.entities.getById(id)
                    .position.getValue(viewer.clock.currentTime)

                // 三维转屏幕坐标 这里获取实体在屏幕中的位置
                var px_position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
                    scene,
                    cartesian
                )
                // 这里转换成经纬高
                let POS = window.Cesium.Cartographic.fromCartesian(cartesian)
               
                // 获取弹窗 然后实时修改弹窗位置
                let popDom = document.getElementById(domId)
                
                var popw = popDom.offsetWidth;
                var poph = popDom.offsetHeight;
                popDom.style.top = px_position.y - poph + "px";
                popDom.style.left = px_position.x - popw / 2 + "px";
               
                 // 这里添加弹窗内容,也是实时变化的
                let infoHTML =   '<p>经度:' + Number((POS.longitude * 180 / Math.PI)).toFixed(4) + '(°)</p>' +
                '<p>纬度:' + Number((POS.latitude * 180 / Math.PI)).toFixed(4) + '(°)</p>' +
                '<p>高度:' + Number((POS.height)).toFixed(4) + '(m)</p>'
                popDom.innerHTML = infoHTML
            }
        }
        
        // 把修改实体弹窗的函数添加的定时器里,进行循环调用
        listenersfunc.prototype.id = id
        let a = helper.add(viewer.clock.onTick, listenersfunc)


    }

4、最好我们点击空白销毁弹窗

  deletePopup(){
        // 找出所有的定时器 找的名称是 listenersfunc 的移除
        let AllListeners = window.viewer.clock.onTick._listeners;
        AllListeners.map(value => {
            if (value.name == "listenersfunc") {
                window.viewer.clock.onTick.removeEventListener(value)

            }
        })

        // 最好清除所以窗口  也可以根据id清除 ,因为我这里展示的是一个 所以用的 class
        document.querySelector(".popupwin")?.remove()

最后就完成了

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值