一、Label 核心概念与基础认知
1.1 什么是 Cesium Label
Cesium Label 是用于在 3D 地球场景中渲染文本标签的核心类,可在指定地理坐标位置显示自定义文本,支持字体、颜色、偏移、缩放、透明度等丰富样式配置,是 Cesium 可视化中最常用的 UI 元素之一(如标注地名、设备名称、数值信息等)。
1.2 核心注意事项
- 禁止直接调用构造函数:
new Cesium.Label()是错误用法,必须通过LabelCollection#add()或viewer.entities.add()(更推荐,封装更友好)创建标签; - 坐标体系:Label 的位置基于笛卡尔坐标系(Cartesian3),需注意高度参考(HeightReference)对实际显示位置的影响;
- 性能考量:大量标签(千级以上)建议使用
LabelCollection而非entities,前者批量渲染性能更优。
二、基础使用:创建第一个 Label
2.1 两种创建方式
方式1:通过 Entity 创建(推荐,封装更友好)
这是最常用的方式,Entity 会自动管理 Label 的生命周期,代码更简洁:
// 初始化 Cesium Viewer
const viewer = new Cesium.Viewer("cesiumContainer");
// 创建标签实体
const labelEntity = viewer.entities.add({
// 标签位置(示例:北京经纬度转笛卡尔坐标)
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
// 标签核心配置
label: {
text: "北京市中心", // 显示文本
font: "24px 微软雅黑", // 字体(CSS 语法)
fillColor: Cesium.Color.WHITE, // 文字填充色
outlineColor: Cesium.Color.BLACK, // 文字轮廓色
outlineWidth: 2, // 轮廓宽度
showBackground: true, // 显示背景框
backgroundColor: new Cesium.Color(0, 0, 0, 0.5), // 背景色(半透明黑色)
backgroundPadding: new Cesium.Cartesian2(10, 5), // 背景内边距(x:左右,y:上下)
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平对齐:居中
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直对齐:底部(标签在位置点下方)
pixelOffset: new Cesium.Cartesian2(0, -20), // 像素偏移(屏幕空间,x右正,y下正)
scale: 1.0, // 缩放比例
show: true // 是否显示
}
});
// 视角聚焦到标签位置
viewer.zoomTo(labelEntity);
方式2:通过 LabelCollection 创建(高性能批量创建)
适合批量创建大量标签,性能优于 Entity:
const viewer = new Cesium.Viewer("cesiumContainer");
const scene = viewer.scene;
// 创建 Label 集合
const labelCollection = new Cesium.LabelCollection();
scene.primitives.add(labelCollection);
// 向集合中添加标签
const label = labelCollection.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
text: "北京市中心",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
showBackground: true,
backgroundColor: new Cesium.Color(0, 0, 0, 0.5),
backgroundPadding: new Cesium.Cartesian2(10, 5),
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -20)
});
2.2 基础属性说明
| 属性名 | 作用 | 常用值/示例 |
|---|---|---|
text |
标签显示文本 | "设备A: 正常" |
font |
字体样式(CSS 语法) | "30px bold sans-serif"、"20px 宋体" |
fillColor |
文字填充色 | Cesium.Color.RED、new Cesium.Color(1,0,0,0.8) |
outlineColor/outlineWidth |
文字轮廓色/宽度 | 轮廓宽度建议 1-3 像素 |
showBackground/backgroundColor |
是否显示背景/背景色 | 背景色建议设置透明度(第四个参数) |
horizontalOrigin/verticalOrigin |
水平/垂直对齐方式 | 水平:LEFT/CENTER/RIGHT;垂直:TOP/CENTER/BOTTOM/BASELINE |
pixelOffset |
屏幕像素偏移 | new Cesium.Cartesian2(10, -10)(右移10px,上移10px) |
三、高级特性:动态效果与交互
3.1 距离相关的动态效果
Cesium Label 支持根据相机与标签的距离,动态调整透明度、缩放、像素偏移,核心依赖 NearFarScalar 类(定义近/远距离对应的属性值,中间值自动插值)。
示例1:距离越远,标签越透明(translucencyByDistance)
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "动态透明度标签",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
// 距离相机 1000 米内:不透明(1.0);8000 米外:完全透明(0.0);中间距离插值
translucencyByDistance: new Cesium.NearFarScalar(1000, 1.0, 8000, 0.0),
// 必须保证 far > near,否则会抛出 DeveloperError
}
});
示例2:距离越远,标签越大(scaleByDistance)
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "动态缩放标签",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
// 距离 1000 米:缩放 1.0;8000 米:缩放 3.0(放大)
scaleByDistance: new Cesium.NearFarScalar(1000, 1.0, 8000, 3.0),
}
});
示例3:距离相关的像素偏移(pixelOffsetScaleByDistance)
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "动态偏移标签",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
pixelOffset: new Cesium.Cartesian2(0, 1.0), // 基础偏移
// 距离 1000 米:偏移缩放 0.0;8000 米:偏移缩放 10.0
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(1000, 0.0, 8000, 10.0),
}
});
3.2 3D 空间偏移(eyeOffset)
eyeOffset 是基于相机视角的 3D 偏移(笛卡尔坐标系),用于让标签始终显示在固定的 3D 空间位置(如标签悬浮在模型上方):
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "悬浮标签",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
// 沿 y 轴(上)偏移 500 米,无论相机视角如何,标签始终在位置点上方 500 米
eyeOffset: new Cesium.Cartesian3(0.0, 500.0, 0.0),
}
});
3.3 高度参考(HeightReference)
控制标签的高度计算方式,解决标签被地形/模型遮挡的问题:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "贴地标签",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
},
// 高度参考:CLAMP_TO_GROUND(贴地)、RELATIVE_TO_GROUND(相对地面高度)、NONE(绝对高度,默认)
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
});
3.4 显示条件(distanceDisplayCondition)
控制标签在指定距离范围内显示:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "仅 500-5000 米可见",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
// 距离相机 500 米内隐藏,500-5000 米显示,5000 米外隐藏
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(500, 5000),
}
});
3.5 禁用深度测试(disableDepthTestDistance)
解决标签被地形/模型遮挡的问题,设置后标签始终显示在最上层:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "始终显示在最上层",
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
// 距离相机 10000 米内禁用深度测试(不会被遮挡)
disableDepthTestDistance: 10000,
}
});
3.6 右键语言支持(enableRightToLeftDetection)
支持阿拉伯语、希伯来语等从右到左的语言显示:
// 全局开启右键语言检测
Cesium.Label.enableRightToLeftDetection = true;
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "זה טקסט בעברית", // 希伯来语文本
font: "24px 微软雅黑",
fillColor: Cesium.Color.WHITE,
}
});
四、交互与动态更新
4.1 动态修改标签属性
Label 创建后,可通过修改 Entity 或 Label 对象的属性实现动态更新:
// 创建标签
const labelEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 100),
label: {
text: "初始文本",
fillColor: Cesium.Color.WHITE,
}
});
// 2 秒后动态修改文本和颜色
setTimeout(() => {
labelEntity.label.text = "动态更新后的文本";
labelEntity.label.fillColor = Cesium.Color.RED;
// 也可以修改位置
labelEntity.position = Cesium.Cartesian3.fromDegrees(116.41, 39.92, 100);
}, 2000);
4.2 标签拾取与点击事件
监听标签的点击事件,实现交互逻辑:
// 监听鼠标点击事件
viewer.screenSpaceEventHandler.setInputAction((event) => {
// 获取点击位置的实体
const pickedObject = viewer.scene.pick(event.position);
if (Cesium.defined(pickedObject) && pickedObject.id === labelEntity) {
alert("你点击了标签:" + labelEntity.label.text);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
五、性能优化建议
- 批量创建用 LabelCollection:千级以上标签优先使用
LabelCollection,而非逐个创建 Entity; - 隐藏而非删除:暂时不需要显示的标签,设置
show: false即可,避免频繁创建/删除; - 合理设置显示范围:通过
distanceDisplayCondition隐藏远距离的标签,减少渲染压力; - 避免过大字体/缩放:字体大小建议 12-36px,缩放比例建议 0.5-2.0,过大易导致像素化且性能下降;
- 复用样式:批量标签复用相同的字体、颜色等样式,减少 GPU 绘制状态切换。
六、常见错误与解决方案
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
DeveloperError: translucencyByDistance.far must be greater than translucencyByDistance.near |
NearFarScalar 的 far 值 ≤ near 值 |
确保 far > near,如 new NearFarScalar(1000, 1.0, 8000, 0.0) |
| 标签被地形/模型遮挡 | 深度测试导致 | 设置 disableDepthTestDistance: Number.POSITIVE_INFINITY 禁用深度测试 |
| 标签显示位置偏移异常 | 对齐方式/偏移设置错误 | 检查 horizontalOrigin/verticalOrigin/pixelOffset 配置 |
| 标签文字乱码 | 字体不支持中文/特殊字符 | 使用系统支持的字体(如微软雅黑、宋体) |
总结
- Cesium Label 是 3D 场景中显示文本的核心类,禁止直接调用构造函数,推荐通过
viewer.entities.add()创建,批量场景用LabelCollection; - 核心特性包括:基础样式配置(字体、颜色、背景)、距离动态效果(透明度/缩放/偏移)、高度参考/显示条件/深度测试等高级配置;
- 性能优化关键:批量创建、合理设置显示范围、隐藏而非删除标签、复用样式。
书签栏