Vue.js2+Cesium1.103.0 十二、绑定多个 DOM 弹窗,并跟随视角实时更新位置
Demo
基于 element-ui 的 Message 封装一个自定义弹窗,添加到页面中,并实时更新位置。
<template><divid="cesium-container"style="width: 100%; height: 100%;"/>
</template><script>
/* eslint-disable no-undef */
import { Message } from 'element-ui'
import Window from './components/Window.vue'
import * as turf from '@turf/turf'function MonomerMessage(h,{component = null,componentName = '',messageData = {},confirmValidate = () => {},...rest}
) {return Message({message: h(Window, {props: { messageData }}),duration: 0,...rest})
}
window.$MyMessage = MonomerMessageexport default {data() {return {}},computed: {},watch: {},mounted() {window.$InitMap()viewer.camera.flyTo({destination: Cesium.Rectangle.fromDegrees(70.01180980018789,20.12881664932077,134.27620577723778,50.568644557429835)})const positions = turf.randomPoint(20, {bbox: [70.01180980018789, 20.12881664932077, 134.27620577723778,50.568644557429835]}).features.map((_, index) => {return {longitude: parseFloat(_.geometry.coordinates[0]).toFixed(7),latitude: parseFloat(_.geometry.coordinates[1]).toFixed(7),altitude: index}})for (let index = 0; index < positions.length; index++) {const element = positions[index]$MyMessage(this.$createElement, {customClass: 'my_message',messageData: element})}},methods: {}
}
</script><style lang="scss">
.el-message {&.my_message {width: max-content;min-width: auto;transition: none;transform: scale(0.5);background-color: rgba($color: #ffffff, $alpha: 0.8);.el-icon-info {display: none;}}
}
</style>
Window.vue
<template><div style="display: flex; align-items: center;"><img:src="require('@/assets/images/site.png')"alt=""style="width: 20px;height: 20px;"><div><div>经度:{{ messageData.longitude }}</div><div>纬度:{{ messageData.latitude }}</div><div>海拔:{{ messageData.altitude }}</div></div></div>
</template><script>
/* eslint-disable no-undef */
export default {name: 'Window',props: {messageData: {type: Object,default() {return {}}}},data() {return {}},mounted() {viewer.scene.preRender.addEventListener(this.eventListener)},beforeDestroy() {viewer.scene.preRender.removeEventListener(this.eventListener)},methods: {eventListener() {const position = Cesium.Cartesian3.fromDegrees(this.messageData.longitude,this.messageData.latitude,this.messageData.altitude)const result = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,position)if (position) {this.$parent.$el.style.left = `${result.x}px`this.$parent.$el.style.top = `${result.y}px`}}}
}
</script>