cesium自定义弹框(信息显示框)

需求:

1.点击图标弹出弹框,点击弹框以外的地方或者弹框上面的“X”关闭弹窗

2.拖动或者放大缩小地图弹框跟随图标移动

3.地球翻转到另一面弹框关闭

效果图:

弹框组件代码(组件就在初始化地图视图里面的容器里面使用即可):

<template>
  <div id="infoCard_" class="infoCard">
    <div class="warninfo">
      <div class="warnInfo_lable">
        <div class="warnInfo_lable_">告警</div>
        <div class="warnInfo_close" @click="()=>{setVisible(false);}"></div>
      </div>
      <div class="warnInfo_msg">
        <div class="row">
          <div class="lable">告警时间</div>
          <div class="value">{{ warnInfo.eventtime }}</div>
        </div>
        <div class="row">
          <div class="lable">告警类型</div>
          <div class="value">{{ warnInfo.eventtype }}</div>
        </div>
        <div class="row">
          <div class="lable">告警内容</div>
          <div class="value">{{ warnInfo.datatype }}</div>
        </div>
        <div class="row">
          <div class="lable">告警地点</div>
          <div class="value">{{ warnInfo.device.fulladdress }}</div>
        </div>
        <div class="row">
          <div class="lable">告警等级</div>
          <div class="value">{{ warnInfo.device.level }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as Cesium from 'cesium';
export default {
  name: 'EarthCard',
  components: {},
  props: {},
  data() {
    return {
      Interval: null,
      isInit: false,
      addDiv: null,
      click_point: null,
      screenC: null,
      isVisible: false,
      removeHandler: null,
      warnInfo: {
        eventtime: "",
        datatype: "",
        eventtype: "",
        device: {
          level: "",
          fulladdress: ""
        }
      },
    }
  },
  computed: {},
  watch: {},
  mounted() {
    this.Interval = setInterval(() => {
      if (window.earth) {
        clearInterval(this.Interval);
        this.Interval = null;
        //初始化弹窗div
        this.initTool();
        this.addLeftClick()
        this.cameraMove()
      }
    }, 200)

  },
  methods: {
    initTool() {
      if (this.isInit) {
        return 0;
      }
      this.addDiv = document.getElementById("infoCard_");
      this.isInit = true;
    },
    //控制弹窗显隐
    setVisible: function (visible) {
      if (!this.isInit) {
        return;
      }
      if (this.addDiv) {
        this.addDiv.style.display = visible ? 'block' : 'none';
      }
    },
    //控制弹窗定位
    showAt: function (position) {
      if (!this.isInit) {
        return;
      }
      if (position) {
        let height = window.innerHeight || document.body.clientHeight;
        let ratio = height / 953;
        this.setVisible(true);
        if (this.addDiv) {
          this.addDiv.style.left = position.x + (ratio * 10) + "px";
          this.addDiv.style.top = position.y - (ratio * 230) + "px";
        }
      }
    },
    addLeftClick() {
      //点击地图事件
      const handler = new Cesium.ScreenSpaceEventHandler(earth.scene.canvas);
      handler.setInputAction((event) => {
        const pick = earth.scene.pick(event.position);
        //选中某模型pick选中的对象
        if (pick && pick.id) {
          let entityID = pick.id._id;
          //标识
          let identifying = entityID.split("_")[0];
          let myEntity = earth.entities.getById(entityID);
          //点击告警图标触发
          if (identifying === "warn") {
            let Cartesian3 = Cesium.Cartesian3.fromDegrees(myEntity.myInfo.lon, myEntity.myInfo.lat, 0);
            let canvasPosition = new Cesium.Cartesian2();
            let position = earth.scene.cartesianToCanvasCoordinates(Cartesian3, canvasPosition)
            this.screenC = new Cesium.Cartesian2(position.x, position.y);
            this.click_point = Cesium.Cartesian3.fromDegrees(myEntity.myInfo.lon, myEntity.myInfo.lat);
            this.warnInfo = myEntity.myInfo;
            this.showAt(this.screenC);
          }
        } else {
          this.setVisible(false);
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    cameraMove() {
      //相机移动开始事件
      earth.scene.camera.moveStart.addEventListener(() => {
        this.removeHandler = earth.scene.postRender.addEventListener(() => {
          // console.log("相机离远了")
          if (this.screenC) {
            this.isVisible = new Cesium.EllipsoidalOccluder(Cesium.Ellipsoid.WGS84, earth.camera.position).isPointVisible(this.click_point);
            if (this.isVisible === false) {
              this.setVisible(false)
            } else {
              this.screenC = Cesium.SceneTransforms.wgs84ToWindowCoordinates(earth.scene, this.click_point);
              if (this.addDiv.style.display === 'block') {
                this.showAt(this.screenC)
              }
            }
          }
        })
      })
      //相机移动结束事件
      earth.scene.camera.moveEnd.addEventListener(() => {
        // console.log("相机靠近了")
        if (this.removeHandler) {
          this.removeHandler();
        }
      })
    },
  }
}
</script>

<style lang="less" scoped>
@ratio: calc(100vh / 953);
.infoCard {
  z-index: 10;
  position: absolute;
  //pointer-events: none;
  display: none;

  .warninfo {
    width: calc(@ratio * 370);
    height: calc(@ratio * 200);
    background-image: url("../image/PC/cockpit/warn_box.png");
    background-size: 100% 100%;
    overflow: hidden;

    .warnInfo_lable {
      width: 89%;
      height: calc(@ratio * 35);
      margin-left: calc(@ratio * 36);
      position: relative;
      //border: 1px solid blue;
      display: flex;
      justify-content: flex-start;
      align-items: center;

      .warnInfo_lable_ {
        color: white;
        margin-left: calc(@ratio * 5);
      }

      .warnInfo_close {
        //border: 1px solid blue;
        width: calc(@ratio * 16);
        height: calc(@ratio * 16);
        margin-left: auto;
        margin-right: calc(@ratio * 7);
        margin-bottom: calc(@ratio * -28);
        z-index: 11;
      }
    }

    .warnInfo_msg {
      margin-top: calc(@ratio * 10);
      width: 100%;
      margin-left: calc(@ratio * 50);

      .row {
        height: 100%;
        width: 100%;
        display: flex;
        margin-top: calc(@ratio * 6);
        color: #FF7676;
        font-size: calc(@ratio * 12);
        background: linear-gradient(90deg, rgba(82, 71, 76, 0.00) 0%, rgba(104, 49, 53, 0.47) 46.35%, rgba(82, 71, 76, 0.00) 100%);

        .lable {
          height: 25%;
          width: 20%;
          overflow: hidden;
        }

        .value {
          height: 25%;
          width: 80%;
          overflow: hidden;
          color: #fff;
        }
      }
    }
  }
}
</style>

弹框组件中earth为初始化地图时创建的地图视图,如下图:

弹框组件中myInfo为创建触发点图标时自定义的属性,里面包含经纬度信息,附创建图标的代码:

//其中earth与弹框组件中的earth一样
 drawIcon = function (item, id, visible) {
  let myEntity = earth.entities.getById(id);
  if (myEntity) {
    myEntity.position = Cesium.Cartesian3.fromDegrees(item.lon, item.lat, 0);
    myEntity.billboard.image = item.url;
    myEntity.billboard.height = item.height;
    myEntity.billboard.width = item.width;
    return;
  }
  let icon = earth.entities.add({
    position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat, 0),
    id: id,
    myInfo: item,
    billboard: {
      // 图像地址,URI或Canvas的属性
      image: item.url,
      // 设置颜色和透明度
      color: Cesium.Color.WHITE.withAlpha(1),
      // 高度(以像素为单位)
      height: item.height,
      // 宽度(以像素为单位)
      width: item.width,
      // 相对于坐标的垂直位置
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      // 是否显示
      show: visible,
    }
  })
}

通过添加div的方式可以实现cesium自定义的弹窗效果。你可以按照以下步骤来创建cesium自定义弹出: 1. 创建cesiumContainer容器:在HTML的script标签内添加一个id为cesiumContainer的容器,用来放置cesium场景。 ```html <script> var viewer = new Cesium.Viewer('cesiumContainer', { // 设置其他参数 }); </script> ``` 2. 创建自定义的弹出内容:使用HTML和CSS创建一个div元素,并设置其样式和内容作为弹出的模板。 ```html <div id="customPopup" style="position: absolute; top: 10px; left: 10px; background-color: white; padding: 10px;"> <h3>Title</h3> <p>Content</p> </div> ``` 3. 监听鼠标事件并显示弹出:在cesium的相应事件监听器中,例如鼠标点击事件或鼠标移动事件,获取事件坐标,并将自定义的弹出添加到cesiumContainer容器中,并设置其位置。 ```javascript viewer.screenSpaceEventHandler.setInputAction(function (event) { var popup = document.getElementById("customPopup"); popup.style.display = "block"; popup.style.left = event.position.x + "px"; popup.style.top = event.position.y + "px"; }, Cesium.ScreenSpaceEventType.LEFT_CLICK); ``` 4. 隐藏弹出:监听其他事件,例如鼠标移出事件或关闭按钮点击事件,隐藏弹出。 ```javascript viewer.screenSpaceEventHandler.setInputAction(function (event) { var popup = document.getElementById("customPopup"); popup.style.display = "none"; }, Cesium.ScreenSpaceEventType.MOUSE_LEAVE); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值