时间轴与动画
Cesium 的时钟不是一个装饰控件。场景里几乎每个属性都可以绑定时间, 轨迹、飞行、生长动画都由同一个 Clock 驱动,改倍速和循环只影响这个时钟。
时钟决定场景里的「现在」
viewer.clock 是一个 Cesium.Clock。它保存三个时间点:
开始、结束、当前。时间轴显示的是开始到结束这段区间,动画播放的是当前时间向前推进的过程。
所有时间都必须是 Cesium.JulianDate,不能传 JavaScript 的 Date。
var clock = viewer.clock;
clock.startTime = Cesium.JulianDate.fromIso8601('2026-10-29T08:00:00Z');
clock.stopTime = Cesium.JulianDate.fromIso8601('2026-10-29T09:00:00Z');
clock.currentTime = clock.startTime.clone();
clock.clockRange = Cesium.ClockRange.LOOP_STOP; // 播到末尾后停住
clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // 用倍速推进
clock.multiplier = 30; // 30 倍速
viewer.timeline.zoomTo(clock.startTime, clock.stopTime);
| 参数 | 取值 | 效果 |
|---|---|---|
clockRange | LOOP_STOP | 到结束时间停止,当前时间停在末尾 |
clockRange | LOOP | 到末尾后跳回开始时间循环播放 |
clockRange | CLAMPED | 不循环,但允许用户拖到区间外,时间被夹住 |
clockStep | SYSTEM_CLOCK_MULTIPLIER | 按真实流逝时间乘以 multiplier 推进 |
clockStep | SYSTEM_CLOCK | 与系统时间同步,multiplier 无效 |
clockStep | TICK_DEPENDENT | 每次 tick 固定前进 multiplier 秒 |
倍速只在 SYSTEM_CLOCK_MULTIPLIER 下生效。改成 SYSTEM_CLOCK 后,
界面上拖倍速滑块不会有任何反应,这是设计如此,不是控件坏了。
用采样属性造一条轨迹
位置随时间变化,就要用 SampledPositionProperty。
它保存若干「时间点 + 坐标」的样本,渲染时按当前时间插值出一个位置。
这种做法比每帧手动改 entity.position 更平滑,也更省 CPU。
var start = Cesium.JulianDate.fromIso8601('2026-10-29T08:00:00Z');
var waypoints = [
[116.20, 39.80], [116.35, 39.95], [116.50, 39.88],
[116.60, 40.02], [116.45, 40.10]
];
var position = new Cesium.SampledPositionProperty();
position.setInterpolationOptions({
interpolationDegree: 1,
interpolationAlgorithm: Cesium.LinearApproximation
});
waypoints.forEach(function (p, i) {
var t = Cesium.JulianDate.addSeconds(start, i * 60, new Cesium.JulianDate());
position.addSample(t, Cesium.Cartesian3.fromDegrees(p[0], p[1], 1200));
});
viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({ start: start, stop: Cesium.JulianDate.addSeconds(start, 300, new Cesium.JulianDate()) })
]),
position: position,
orientation: new Cesium.VelocityOrientationProperty(position),
model: {
uri: '/models/plane.glb',
minimumPixelSize: 48,
maximumScale: 20000
},
path: {
resolution: 60,
width: 3,
leadTime: 0,
trailTime: 300,
material: Cesium.Color.fromCssColorString('#ffb400')
}
});
VelocityOrientationProperty 根据位置的差分自动算出朝向,
模型不用再手动设 orientation。样本点越密,转向越跟得上;
点太稀疏时模型会在拐点处突然掉头。
线性插值不等于匀速。每个样本间隔 60 秒,但两点之间的实际距离不同, 模型的瞬时速度就会忽快忽慢。需要匀速运动时,按距离等分采样点,而不是按时间等分。
按时间段改颜色和可见性
颜色、显示开关这类属性可以用 TimeIntervalCollectionProperty,
给不同时间区间配不同值。播放到某个区间,属性自动切换,不需要监听时钟事件。
var highlight = new Cesium.TimeIntervalCollectionProperty();
highlight.intervals.addInterval(new Cesium.TimeInterval({
start: Cesium.JulianDate.addSeconds(start, 120, new Cesium.JulianDate()),
stop: Cesium.JulianDate.addSeconds(start, 210, new Cesium.JulianDate()),
isStartIncluded: true,
isStopIncluded: false,
data: Cesium.Color.fromCssColorString('#ff5252')
}));
highlight.intervals.addInterval(new Cesium.TimeInterval({
start: Cesium.JulianDate.addSeconds(start, 210, new Cesium.JulianDate()),
stop: Cesium.JulianDate.addSeconds(start, 300, new Cesium.JulianDate()),
data: Cesium.Color.fromCssColorString('#4d9bff')
}));
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.391, 39.907, 260),
point: {
pixelSize: 14,
color: highlight,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2
}
});
区间之外的时刻没有值,属性取默认值。想让起点之前也有颜色,
加一个从 startTime 到第一个区间开始的时间段即可。
时间轴控件的外观
时间轴默认显示刻度与当前时间标签。展示型页面通常把它简化: 隐藏倍速滑块、改标签格式、固定显示区间。
viewer.timeline.makeLabel = function (time) {
return Cesium.JulianDate.toIso8601(time).slice(11, 16); // 只显示 HH:MM
};
// 清空倍速滑块刻度,只保留播放与暂停
viewer.animation.viewModel.shuttleRingTicks = [];
viewer.timeline.zoomTo(clock.startTime, clock.stopTime);
注意事项
- 开启
scene.requestRenderMode后,时间推进不会自动重绘;需要调用viewer.scene.requestRender(),或者保持时钟暂停、只在数据变化时渲染。 SampledPositionProperty的样本必须按时间递增加入;倒序加入会让插值区间找不到。path的trailTime是「尾迹长度」,单位是秒,不是点数;设置过大时整条轨迹都会画出来,等于关闭尾迹效果。- 实体没有设置
availability时,在时钟区间外仍然可见,容易被误认为动画没生效。 - 用
clock.onTick做逐帧逻辑时要判断clock.canAnimate,暂停状态下也会触发回调。
动画卡顿先看数据量。一条轨迹几千个样本时,插值和路径几何的更新都会变慢。
把 path.resolution 从 60 降到 30,并把轨迹拆成多段按需显示,通常比调时钟参数有效。
经纬志(2026)。《时间轴与动画》。https://www.jingweizhi.com/cesium/tutorial/time-animation.html(访问日期 2026-11-03)。