Vue.js2+Cesium1.103.0 十二、绑定多个 DOM 弹窗,并跟随视角实时更新位置
Demo
基于 element-ui 的 Message 封装一个自定义弹窗,添加到页面中,并实时更新位置。
<template>
<div
id="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 = MonomerMessage
export 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>