思路:
1.在页面中创建一个div标签;
2.确定标签在三维场景中的三维位置;并计算三维位置的屏幕坐标;
3.在每一帧的渲染中都计算一下这个三维坐标的屏幕位置,并把屏幕位置赋给标签。
4.当转到地球背面时,如果不想显示弹窗,则隐藏。
具体实现:
1.创建div标签
标签样式:
.tag{
position: absolute;
background-color: MidnightBlue;
background-color:rgba(0,10,40);
border-top-left-radius: 10px;
border-bottom-right-radius:10px;
opacity: 0.5;
font-size: 4px;
color: aqua;
width: 36px;
height: 44px;
padding: 1px 1px 1px;
}
创建div时,最好是id和它要跟随的对象一致,方便场景中查找位置:
//txt1 txt2 txt3 为div中要显示的文本,具体样式可修改 innerHTML那一行
function addDom(id,txt1, txt2, txt3,) {
let addDivDom = document.createElement('div');
let bodyDom = document.getElementsByClassName("cesium-viewer")[0];
bodyDom.insertBefore(addDivDom, bodyDom.lastChild);
addDivDom.classList = 'tag';
addDivDom.id = id;
addDivDom.innerHTML = '<span style="color:white;font-size: 10px;padding: 5px">' + txt1 + '</span>' + '<span style="font-size: 11px;font-weight: bold">' + txt2 + '</span>' + '<p style="padding: 5px;margin-top: -3px;">' + txt3 + '</p>';
}
2.确定标签在三维场景中的位置并转为屏幕坐标
//三维笛卡尔坐标转屏幕坐标
function transPosition(position) {
return Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position);
}
(1).指定位置(经纬度)
function fixDomPosition(domId,position){
var dom=document.getElementById(domId);
var cartesian=Cesium.Cartesian3.fromDegrees(position.longitude,position.latitude,position.height);
var winPosi = transPosition(cartesian);
if(winPosi!==undefined&&winPosi!==null){
dom.style.display=""
dom.style.left=winPosi.x+"px";
dom.style.top=winPosi.y+"px";
}else{
dom.style.display="none"
}
}
(2).跟随相同ID的模型
function modelFixDom(domId) {
var entity=viewer.entities.getById(domId);
var cartesian = entity.position._value;
var dom=document.getElementById(domId);
var winPosi = transPosition(cartesian);
if(winPosi!==undefined&&winPosi!==null){
dom.style.display=""
dom.style.left=winPosi.x+"px";
dom.style.top=winPosi.y+"px";
}else{
dom.style.display="none"
}
}
3.在每一帧的渲染中都计算一下这个三维坐标的屏幕位置,并把屏幕位置赋给标签。
viewer.scene.preRender.addEventListener(function () {
modelFixDom("modelDom");
var position=new Cesium.Cartographic(116.587678,40.56756,0);
fixDomPosition("fixDom",position);
})
4.如果不想地球转到背面仍显示标签,则加个判断距离判断
function modelFixDom(domId) {
var entity=viewer.entities.getById(domId);
var cartesian = entity.position._value;
var dom=document.getElementById(domId);
var winPosi = transPosition(cartesian);
if(winPosi!==undefined&&winPosi!==null){
var res = enableShow(cartesian);
if(res){
dom.style.display=""
dom.style.left=winPosi.x+"px";
dom.style.top=winPosi.y+"px";
}else{
dom.style.display="none"
}
}else{
dom.style.display="none"
}
}
function enableShow(cartesian){
var res=false;
var e = cartesian,
f = viewer.scene.camera.position,
g = viewer.scen