在地图开发中,气泡框是项目中经常要用到的功能,那么在cesium中如何实现气泡信息框并让其跟随地图移动呢?
原理就是在地图移动时,将地理坐标转换为屏幕坐标,并实时地传给气泡框,更改其位置即可,这里主要用到scene.postRender
核心代码:
//实时更改位置
this.renderListener = this.viewer.scene.postRender.addEventListener(this.render, this)
var position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, geometry)
if (!position) {
return
}
if (this.popupContainer) {
this.popupContainer.style.left = position.x - this.popupContainer.offsetWidth / 2 + 'px'
this.popupContainer.style.top = position.y - this.popupContainer.offsetHeight - 10 + 'px'
}
viewer.entities.add({
id: 'point',
position: new Cesium.Cartesian3.fromDegrees(117.456, 33.5633),
point: {
pixelSize: 6,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2
}
});
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (evt) {
let pick = this.viewer.scene.pick(evt.position);
if (pick && pick.id) {
initPopup();
} else {
if (popupObj) {
popupObj.remove();
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
CesiumPopup.js完整代码
(function (window, document) {
var CesiumPopup = function (viewer, options) {
if (!(this instanceof CesiumPopup)) return new CesiumPopup(viewer, options);
this.viewer = viewer
this.position = options.position;
this.options = this.extend({}, options);
var popupContainer = document.createElement("div");
popupContainer.classList.add('popup');
var popupInner = '<div class="popup-title">标题</div><div class="popup-body">内容</div>';
popupContainer.innerHTML = popupInner;
popupContainer.style.display = 'none';
viewer.cesiumWidget.container.appendChild(popupContainer);
popupContainer.style.cssText = "display: none;position: absolute;left: 0;top: 0;min-width: 200px;z-index:9999;";
this.popupContainer = popupContainer;
// 初始化
this.init();
};
CesiumPopup.prototype = {
init: function () {
if (this.position) {
this.popupContainer.style.display = 'block'
this.renderListener = this.viewer.scene.postRender.addEventListener(this.render, this)
}
},
render: function () {
var ellipsoid = this.viewer.scene.globe.ellipsoid;
var geometry = Cesium.Cartesian3.fromDegrees(
this.position[0],
this.position[1],
0,
ellipsoid
);
if (!geometry) return
var position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, geometry)
if (!position) {
return
}
if (this.popupContainer) {
this.popupContainer.style.left = position.x - this.popupContainer.offsetWidth / 2 + 'px'
this.popupContainer.style.top = position.y - this.popupContainer.offsetHeight - 10 + 'px'
}
},
remove: function () {
if (this.popupContainer) {
this.popupContainer.parentNode.removeChild(this.popupContainer)
this.popupContainer = null
}
if (this.renderListener) {
this.renderListener()
this.renderListener = null
}
if (this.viewer) {
this.viewer = null
}
},
extend: function (obj, obj2) {
for (var k in obj2) {
obj[k] = obj2[k];
}
return obj;
},
};
window.CesiumPopup = CesiumPopup;
}(window, document));