CSS 元素
CSS DOM Overlay

你将学到什么
- 不用 Entity,用 原生 HTML 做信息面板
- postRender 每帧把世界坐标投影到屏幕像素
- SceneTransforms.worldToWindowCoordinates 坐标转换
- 背面/过远时隐藏 DOM
效果说明
北京坐标处有一个可点击的蓝色边框 div「2dDOM」,随相机移动始终钉在地标上方;过远或转到地球背面时自动隐藏。
核心概念
Cesium 内置 HtmlOverlay / InfoBox 等方案;本案例演示 最小自实现:
地理坐标 (Cartesian3)
↓ worldToWindowCoordinates
屏幕像素 (x, y)
↓ CSS transform: translate
DOM 定位容器层级
js
const css2dContainer = document.createElement('div');
Object.assign(css2dContainer.style, {
position: 'absolute', top: '0', left: '0',
pointerEvents: 'none', // 容器穿透,子元素可单独开启
zIndex: '1',
});
box.appendChild(css2dContainer);postRender 同步
js
viewer.scene.postRender.addEventListener(() => {
const windowCoord = Cesium.SceneTransforms.worldToWindowCoordinates(
viewer.scene, position
);
if (windowCoord) {
DOM.style.transform = `translate(${windowCoord.x}px, ${windowCoord.y - offsetHeight}px)`;
}
// 距离过远则隐藏
const maxDistance = ...;
DOM.style.display = distance > maxDistance ? 'none' : 'block';
});与 Three.js CSS2DRenderer 对比
思路相同:每帧投影 + translate。Cesium 需自己算 maxDistance 处理背面。
实现步骤
- 在 Viewer 容器外再套一层
css2dContainer - 创建样式化 div,设置
pointerEvents: 'all'以响应点击 setCss2dDom(viewer, DOM, [lon, lat, height])注册 postRender- 返回 destroy 函数:移除 DOM 并取消监听
代码要点
js
function setCss2dDom(viewer, DOM, position) {
if (!(position instanceof Cesium.Cartesian3))
position = Cesium.Cartesian3.fromDegrees(...position);
css2dContainer.appendChild(DOM);
const destroy = viewer.scene.postRender.addEventListener(() => {
const windowCoord = Cesium.SceneTransforms.worldToWindowCoordinates(
viewer.scene, position
);
if (windowCoord) {
DOM.style.transform = `translate(${windowCoord.x}px, ${windowCoord.y - DOM.offsetHeight}px)`;
}
});
return () => { css2dContainer.removeChild(DOM); destroy(); };
}源码
完整源码见 GitHub。
小结
基础功能 · Cesium.js · 5/19
