div随轨迹运动 · cssElementTrack · ▶ 在线运行案例
案例合集: 三维可视化功能案例(threehub.cn)
开源仓库github地址: https://github.com/z2586300277/three-cesium-examples
**400个案例代码: ** 网盘链接

你将学到什么
- Cesium Entity 高层实体 API
效果说明
本案例演示 div随轨迹运动 效果:Cesium飞行轨迹跟踪弹窗示例,在飞行器沿轨迹移动时,显示一个跟随的弹窗显示当前位置信息;核心用到 Cesium。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。
核心概念
- Viewer 聚合 Scene、Camera、Clock 与渲染循环,是 Cesium 应用入口。
- Entity 面向点线面/模型/标签的高层 API;与 Primitive 相比更适合交互与属性驱动。
- 阅读下方完整源码时,建议从
init/load/animate三条主线入手,再深入 shader 与工具函数。
实现步骤
- 创建 Viewer,配置地形/影像(若案例需要)并设置初始相机
- 在
requestAnimationFrame循环中更新状态并 render(Cesium 为viewer.render或自动渲染)
代码要点
import * as Cesium from 'cesium'
/**
* Cesium飞行轨迹跟踪弹窗示例
* 在飞行器沿轨迹移动时,显示一个跟随的弹窗显示当前位置信息
*/
// ==================== 初始化区域 ====================
/**
* 获取Cesium容器元素
* @type {HTMLElement}
*/
const box = document.getElementById('box')
/**
* 初始化Cesium Viewer实例
* @type {Cesium.Viewer}
*/
const viewer = new Cesium.Viewer(box, {
animation: false, // 启用动画器件
baseLayerPicker: false, // 是否显示图层选择器,右上角图层选择按钮
baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl(GLOBAL_CONFIG.getLayerUrl())),
fullscreenButton: false, // 是否显示全屏按钮,右下角全屏选择按钮
timeline: false, // 是否显示时间轴
infoBox: false, // 是否显示信息框
})
// 隐藏Cesium Logo
viewer._cesiumWidget._creditContainer.style.display = "none";
// 启用地形深度测试,确保正确渲染
viewer.scene.globe.depthTestAgainstTerrain = false
/**
* 设置相机初始视角
* 将视角定位到飞行轨迹中心区域
*/
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(123, 34.32, 100000), // 目标位置
duration: 0 // 飞行时间(秒)
})
// ==================== 弹窗元素创建区域 ====================
/**
* 创建CSS元素 - 跟踪信息弹窗
* 用于显示飞行器的实时位置信息
* @type {HTMLDivElement}
*/
const trackInfoElement = document.createElement('div')
// 设置弹窗样式:白底黑字,带阴影和圆角
Object.assign(trackInfoElement.style, {
backgroundColor: 'rgba(255, 255, 255, 0.9)', // 白色半透明背景
color: 'black', // 黑色文字
padding: '8px 12px', // 内边距
borderRadius: '6px', // 圆角
fontWeight: 'bold', // 粗体文字
fontSize: '14px', // 字体大小
fontFamily: 'Arial, sans-serif', // 字体族
zIndex: 'auto',
position: 'absolute',
transform: 'translate(-50%, -110%)', // 使元素中心对齐定位点上方
textAlign: 'center',
minWidth: '150px' // 最小宽度
})
// 将弹窗元素添加到CSS容器中
box.appendChild(trackInfoElement)
// ==================== 飞行轨迹数据区域 ====================
/**
* 定义飞行轨迹点
* 包含一系列经纬度和高度坐标,用于构建飞行路径
* @type {Array<Cesium.Cartesian3>}
*/
const flightPositions = [
Cesium.Cartesian3.fromDegrees(122.50, 34.70, 10000), // 终点
Cesium.Cartesian3.fromDegrees(123.46, 33.92, 10000), // 起点:北京附近
]
// ==================== 飞行器实体创建区域 ====================
/**
* 创建飞行路线实体
* 在地图上可视化显示飞行轨迹
* @type {Cesium.Entity}
*/
const flightPath = viewer.entities.add({
name: '飞行路线',
polyline: {
positions: flightPositions, // 路线点坐标
width: 3, // 线条宽度
material: Cesium.Color.RED, // 蓝色半透明材质
clampToGround: false // 不贴地
}
})
/**
* 创建飞行器模型实体
* 使用采样位置属性和速度方向属性实现沿轨迹移动
* @type {Cesium.Entity}
*/
const myPoint = viewer.entities.add({
position: new Cesium.SampledPositionProperty(), // 采样位置属性
point: {
pixelSize: 10,
color: Cesium.Color.YELLOW,
},
})
// ==================== 飞行路径设置区域 ====================
/**
* 获取飞行器位置属性,用于设置轨迹点
* @type {Cesium.SampledPositionProperty}
*/
const position = myPoint.position
/**
* 每个轨迹点之间的时间间隔(秒)
* @type {number}
*/
const timeStep = 20
/**
* 创建时间序列,为每个轨迹点分配时间
* 通过在不同时间点采样位置实现平滑移动效果
*/
for (let i = 0; i < flightPositions.length; i++) {
// 计算当前点的时间戳
const time = Cesium.JulianDate.addSeconds(
viewer.clock.startTime, // 起始时间
i * timeStep, // 时间偏移
new Cesium.JulianDate() // 结果时间
)
// 为该时间点添加位置采样
position.addSample(time, flightPositions[i])
}
viewer.clock.shouldAnimate = true // 启动动画
// 监听场景更新事件
viewer.scene.preUpdate.addEventListener(updateTrackInfoPosition)
function updateTrackInfoPosition() {
// 获取飞行器在当前时间的精确位置
const currentPosition = myPoint.position.getValue(viewer.clock.currentTime)
// 如果飞行器位置存在,更新弹窗位置
if (currentPosition) {
// 将地球上的三维位置转换为屏幕坐标
const windowCoord = Cesium.SceneTransforms.worldToWindowCoordinates(
viewer.scene, // 场景对象
currentPosition // 世界坐标
)
// 如果坐标转换成功,更新弹窗位置和内容
if (windowCoord) {
// 设置弹窗在屏幕上的位置
trackInfoElement.style.left = windowCoord.x + 'px'
trackInfoElement.style.top = windowCoord.y + 'px'
trackInfoElement.style.display = 'block'
// 将笛卡尔坐标转换为地理坐标(经纬度)
const cartographic = Cesium.Cartographic.fromCartesian(currentPosition)
// 格式化地理坐标信息
const longitude = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6) // 经度
const latitude = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6) // 纬度
const height = cartographic.height.toFixed(0) // 高度
// 更新弹窗内容,显示实时位置信息
trackInfoElement.innerHTML = `
<div style="text-align: left;">
<div>经度: ${longitude}°</div>
<div>纬度: ${latitude}°</div>
<div>高度: ${height}米</div>
</div>
`
} else {
// 坐标转换失败时隐藏弹窗
trackInfoElement.style.display = 'none'
}
} else {
// 飞行器位置不存在时隐藏弹窗
trackInfoElement.style.display = 'none'
}
}
完整源码:GitHub
小结
- 本文提供 div随轨迹运动 完整 Cesium.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
- 更多 Cesium.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库