写点什么

JSAPIThree 时间系统学习笔记:让场景随时间变化

作者:map_3d_vis
  • 2025-11-20
    北京
  • 本文字数:7726 字

    阅读完需:约 25 分钟

作为一个刚开始学习 mapvthree 的小白,今天要学习时间系统了!听说这个系统可以让场景根据时间变化,实现真实的昼夜交替效果,就像真实世界一样!想想就激动!

第一次听说时间系统

今天在文档里看到了"时钟"这个词,一开始我还以为是用来显示时间的,结果查了一下才知道,原来这是用来控制场景时间的系统!


文档说时间系统可以:


  • 控制动态天空的光照效果

  • 实现真实的昼夜交替

  • 模拟日出日落

  • 控制场景的氛围


我的理解:简单说就是让场景知道"现在是几点",然后根据时间自动调整光照、天空颜色等效果!就像真实世界一样,早上是亮的,晚上是暗的!

第一步:发现引擎的时钟属性

作为一个初学者,我习惯先看看引擎有哪些属性。文档说 engine.clock 就是时钟对象!


我的发现:原来引擎创建后,就自动有了一个时钟对象!不需要手动创建,直接用就行!


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');const engine = new mapvthree.Engine(container);
// 时钟对象已经自动创建了!console.log(engine.clock); // 可以访问时钟对象
复制代码


我的理解engine.clock 就是时间系统的入口,所有时间相关的操作都通过它来完成。

第二步:设置当前时间

文档说可以通过 engine.clock.currentTime 来设置当前时间。我试了试:


// 设置为下午 2 点engine.clock.currentTime = new Date('2025-05-15 14:00:00');
复制代码


我的发现:设置时间后,如果场景里有动态天空,天空的颜色和光照会立即变化!


我的尝试:我写了个简单的测试:


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, { map: { center: [116.404, 39.915], range: 1000, pitch: 80, }, rendering: { enableAnimationLoop: true, sky: new mapvthree.DynamicSky(), // 添加动态天空 }});
// 设置为白天(下午 2 点)engine.clock.currentTime = new Date('2025-05-15 14:00:00');
复制代码


我的观察:天空变成了明亮的蓝色,光照很强,就像真实的白天一样!


我的理解new Date() 可以创建一个日期对象,格式是 '年-月-日 时:分:秒'。这样就能精确控制场景的时间了!

第三步:尝试不同的时间

看到效果后,我开始好奇:不同时间会有什么不同的效果?


我试了几个不同的时间:


// 早上 6 点(日出)engine.clock.currentTime = new Date('2025-05-15 06:00:00');
// 中午 12 点(正午)engine.clock.currentTime = new Date('2025-05-15 12:00:00');
// 下午 6 点(黄昏)engine.clock.currentTime = new Date('2025-05-15 18:00:00');
// 晚上 10 点(夜晚)engine.clock.currentTime = new Date('2025-05-15 22:00:00');
复制代码


我的发现


  • 早上 6 点:天空是橙红色的,就像日出一样

  • 中午 12 点:天空是明亮的蓝色,光照最强

  • 下午 6 点:天空是橙黄色的,就像黄昏

  • 晚上 10 点:天空是深蓝色的,光照很暗


我的感受:太神奇了!不同时间真的有完全不同的视觉效果!就像真实世界一样!


我的想法:如果做一个按钮,点击后切换不同时间,就能看到场景在不同时段的样子了!

第四步:了解时钟模式

看到不同时间的效果后,我想:能不能让时间自动流逝,看到完整的昼夜交替过程?


文档说可以设置 engine.clock.tickMode 来控制时间的行为!有四种模式可以选择:

模式 1:TICK_NONE(无限制模式)

engine.clock.tickMode = engine.clock.TICK_NONE;
复制代码


我的理解:时间不会自动流逝,只能手动设置。这是默认模式。


我的尝试


engine.clock.tickMode = engine.clock.TICK_NONE;engine.clock.currentTime = new Date('2025-05-15 10:00:00');// 时间会停留在 10:00:00,不会自动变化
复制代码


我的发现:时间不会自动流逝,适合需要精确控制时间的场景。

模式 2:TICK_NORMAL(正常模式)

engine.clock.tickMode = engine.clock.TICK_NORMAL;
复制代码


我的理解:时间会正常自动流逝,不受起止时间限制。


我的尝试


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, { map: { center: [116.404, 39.915], range: 1000, pitch: 80, }, rendering: { enableAnimationLoop: true, // 必须开启循环渲染 sky: new mapvthree.DynamicSky(), }});
// 设置初始时间engine.clock.currentTime = new Date('2025-05-15 06:00:00');
// 开启时间自动流逝(正常模式)engine.clock.tickMode = engine.clock.TICK_NORMAL;
复制代码


我的发现:时间开始自动流逝了!天空的颜色和光照会慢慢变化,从日出到正午,再到黄昏,最后到夜晚,然后继续流逝,不会循环!


我的感受:太酷了!就像看延时摄影一样,能看到完整的昼夜交替过程!


我的注意:要让时间自动流逝,必须开启 enableAnimationLoop,否则时间不会更新!

模式 3:TICK_LOOP(循环模式)

engine.clock.tickMode = engine.clock.TICK_LOOP;
复制代码


我的理解:时间会在起止时间之间循环,到达停止时间后会自动回到开始时间。


我的尝试


// 设置开始时间(早上 6 点)engine.clock.startTime = new Date('2025-05-15 06:00:00');
// 设置停止时间(晚上 10 点)engine.clock.stopTime = new Date('2025-05-15 22:00:00');
// 设置当前时间engine.clock.currentTime = new Date('2025-05-15 10:00:00');
// 开启循环模式engine.clock.tickMode = engine.clock.TICK_LOOP;
复制代码


我的发现:时间会在 6:00 到 22:00 之间循环!到达 22:00 后,会自动跳回 6:00,然后继续流逝!


我的想法:这个模式很适合做演示,可以反复播放一天的场景变化!

模式 4:TICK_CLAMP(限制模式)

engine.clock.tickMode = engine.clock.TICK_CLAMP;
复制代码


我的理解:时间会被限制在起止时间之间,到达边界后会停止。


我的尝试


// 设置开始时间(早上 6 点)engine.clock.startTime = new Date('2025-05-15 06:00:00');
// 设置停止时间(晚上 10 点)engine.clock.stopTime = new Date('2025-05-15 22:00:00');
// 设置当前时间engine.clock.currentTime = new Date('2025-05-15 10:00:00');
// 开启限制模式engine.clock.tickMode = engine.clock.TICK_CLAMP;
复制代码


我的发现:时间会在 6:00 到 22:00 之间流逝,到达 22:00 后会停止,不会继续!


我的想法:这个模式适合需要限制时间范围的场景,比如只展示白天的效果。

第五步:设置起止时间

看到不同的时钟模式后,我开始好奇:startTimestopTime 是怎么用的?


文档说可以设置开始时间和停止时间,用来限制时间的范围!


// 设置开始时间engine.clock.startTime = new Date('2025-05-15 06:00:00');
// 设置停止时间engine.clock.stopTime = new Date('2025-05-15 22:00:00');
复制代码


我的理解startTimestopTime 定义了时间的范围,配合 TICK_LOOPTICK_CLAMP 模式使用。


我的尝试


// 设置时间范围(早上 6 点到晚上 10 点)engine.clock.startTime = new Date('2025-05-15 06:00:00');engine.clock.stopTime = new Date('2025-05-15 22:00:00');
// 设置当前时间engine.clock.currentTime = new Date('2025-05-15 10:00:00');
// 使用循环模式engine.clock.tickMode = engine.clock.TICK_LOOP;
复制代码


我的发现


  • 如果当前时间在范围内,时间会正常流逝

  • 如果使用 TICK_LOOP,到达停止时间后会循环到开始时间

  • 如果使用 TICK_CLAMP,到达停止时间后会停止


我的想法:这样就能精确控制时间的范围了,比如只展示白天的时间段!

第六步:控制时间流速

看到时间自动流逝后,我开始好奇:能不能控制时间流逝的速度?


文档说可以通过 engine.clock.speed 来控制时间流速!


// 设置时间流速倍率engine.clock.speed = 1000; // 1000 倍速
复制代码


我的理解speed 是时间流速的倍率,1 是正常速度,1000 就是 1000 倍速,时间会过得很快!


我的尝试


// 正常速度engine.clock.speed = 1;
// 10 倍速engine.clock.speed = 10;
// 100 倍速engine.clock.speed = 100;
// 1000 倍速(很快!)engine.clock.speed = 1000;
复制代码


我的发现


  • speed = 1:时间过得很慢,适合仔细观察

  • speed = 100:时间过得比较快,能看到明显的变化

  • speed = 1000:时间过得很快,几分钟就能看到一整天


我的想法:如果做演示,可以用较大的 speed 值,让观众快速看到昼夜交替效果!

第七步:重置时钟

看到时间自动流逝后,我想:能不能重置时间到开始时间?


文档说可以用 reset() 方法来重置时钟!


// 重置时钟到开始时间engine.clock.reset();
复制代码


我的理解reset() 会把当前时间重置为 startTime,如果没有设置 startTime,则重置为当前时间。


我的尝试


// 设置开始时间engine.clock.startTime = new Date('2025-05-15 06:00:00');
// 设置当前时间(已经流逝了一段时间)engine.clock.currentTime = new Date('2025-05-15 15:00:00');
// 重置到开始时间engine.clock.reset();
// 现在 currentTime 又变回 06:00:00 了console.log(engine.clock.currentTime); // 2025-05-15 06:00:00
复制代码


我的发现:重置后,时间会回到开始时间,就像重新开始一样!


我的想法:如果做演示,可以用重置功能让场景重新开始播放!

第八步:使用 UTC 时间

看到 currentTime 后,我开始好奇:什么是 UTC 时间?


文档说还有 currentTimeUTC 属性,可以获取或设置 UTC 时间!


我的理解:UTC 是世界标准时间,不受时区影响。currentTime 是本地时间,currentTimeUTC 是 UTC 时间。


我的尝试


// 设置本地时间engine.clock.currentTime = new Date('2025-05-15 14:00:00');
// 获取 UTC 时间const utcTime = engine.clock.currentTimeUTC;console.log(utcTime);
// 设置 UTC 时间engine.clock.currentTimeUTC = new Date('2025-05-15 06:00:00');
复制代码


我的发现:设置 UTC 时间后,本地时间会自动转换!


我的想法:如果做国际化应用,可能需要用 UTC 时间来统一管理!

第九步:设置时区偏移

看到 UTC 时间后,我开始好奇:能不能设置时区?


文档说可以通过 timeZoneOffset 来设置时区偏移量!


// 设置时区偏移(东八区,北京时间)engine.clock.timeZoneOffset = 8;
// 设置时区偏移(西五区,纽约时间)engine.clock.timeZoneOffset = -5;
复制代码


我的理解:时区偏移量是相对于 UTC 的小时数,东八区是 +8,西五区是 -5。


我的尝试


// 设置为东八区(北京时间)engine.clock.timeZoneOffset = 8;
// 设置 UTC 时间engine.clock.currentTimeUTC = new Date('2025-05-15 06:00:00');
// 本地时间会自动转换为 14:00:00(UTC+8)console.log(engine.clock.currentTime); // 2025-05-15 14:00:00
复制代码


我的发现:设置时区偏移后,UTC 时间和本地时间会自动转换!


我的想法:如果做全球应用,可以用时区偏移来适配不同地区的时间!

第十步:配合动态天空使用

文档说时间系统主要是配合动态天空使用的。我试了试:


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, { map: { center: [116.404, 39.915], range: 1000, pitch: 80, }, rendering: { enableAnimationLoop: true, sky: new mapvthree.DynamicSky(), // 动态天空 }});
// 设置时间engine.clock.currentTime = new Date('2025-05-15 10:00:00');
// 开启时间自动流逝engine.clock.tickMode = engine.clock.TICK_NORMAL;
复制代码


我的发现:动态天空会根据时间自动调整:


  • 天空颜色(蓝色、橙色、深蓝色等)

  • 光照强度(白天亮,晚上暗)

  • 太阳位置(早上在东边,中午在头顶,晚上在西边)


我的理解:时间系统控制"时间",动态天空根据"时间"来渲染效果,两者配合就能实现真实的昼夜交替!


我的注意:如果没有动态天空,设置时间可能看不到明显效果,因为只有动态天空会根据时间变化!

第十一步:初始化时配置时钟

看到这么多属性后,我开始想:能不能在创建引擎时就配置时钟?


文档说可以在引擎初始化时通过 clock 配置项来设置时钟!


const engine = new mapvthree.Engine(container, {    map: {        center: [116.404, 39.915],        range: 1000,    },    rendering: {        enableAnimationLoop: true,        sky: new mapvthree.DynamicSky(),    },    clock: {        currentTime: new Date('2025-05-15 10:00:00'),        speed: 100,        startTime: new Date('2025-05-15 06:00:00'),        stopTime: new Date('2025-05-15 22:00:00'),        tickMode: 2, // TICK_LOOP = 2        timeZoneOffset: 8,    }});
复制代码


我的发现:可以在初始化时一次性配置所有时钟参数,更方便!


我的理解


  • currentTime:当前时间,未设置则使用当天 10:00:00

  • speed:时间流速倍率

  • startTime:开始时间,未设置则使用当前时间

  • stopTime:停止时间,未设置则使用当前时间

  • tickMode:时钟模式

  • timeZoneOffset:时区偏移量


我的尝试


const engine = new mapvthree.Engine(container, {    map: {        center: [116.404, 39.915],        range: 1000,        pitch: 80,    },    rendering: {        enableAnimationLoop: true,        sky: new mapvthree.DynamicSky(),    },    clock: {        currentTime: new Date('2025-05-15 08:00:00'),        speed: 100,        tickMode: 2, // TICK_LOOP = 2    }});
复制代码


我的发现:初始化时就配置好了,代码更简洁!

第十二步:实际应用场景

学到这里,我开始想:时间系统能用在什么地方呢?

场景 1:展示不同时段的数据

我想展示不同时段的数据变化,比如:


  • 早上:显示早高峰数据

  • 中午:显示午间数据

  • 晚上:显示夜间数据


// 切换到早上engine.clock.currentTime = new Date('2025-05-15 08:00:00');// 显示早高峰数据showMorningData();
// 切换到中午engine.clock.currentTime = new Date('2025-05-15 12:00:00');// 显示午间数据showNoonData();
// 切换到晚上engine.clock.currentTime = new Date('2025-05-15 20:00:00');// 显示夜间数据showNightData();
复制代码


我的想法:这样就能让用户看到不同时段的数据变化,更直观!

场景 2:创建时间流逝演示

我想创建一个演示,自动播放一天的场景变化:


// 从早上 6 点开始engine.clock.currentTime = new Date('2025-05-15 06:00:00');
// 开启时间自动流逝,100 倍速engine.clock.tickMode = engine.clock.TICK_NORMAL;engine.clock.speed = 100;
复制代码


我的想法:这样观众就能在几分钟内看到完整的昼夜交替过程,很有视觉冲击力!

场景 3:根据真实时间显示场景

我想让场景显示当前真实时间:


// 设置为当前时间engine.clock.currentTime = new Date();
// 开启时间自动流逝(正常速度)engine.clock.tickMode = engine.clock.TICK_NORMAL;engine.clock.speed = 1;
复制代码


我的想法:这样场景就会和真实世界同步,用户看到的就是当前时间对应的场景!

第十三步:做一个完整的示例

我想写一个完整的示例,把学到的都用上:


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, { map: { center: [116.404, 39.915], range: 1000, pitch: 80, }, rendering: { enableAnimationLoop: true, sky: new mapvthree.DynamicSky(), }});
// 设置初始时间为早上 6 点engine.clock.currentTime = new Date('2025-05-15 06:00:00');
// 开启时间自动流逝engine.clock.tickMode = engine.clock.TICK_NORMAL;
// 设置时间流速(100 倍速,快速演示)engine.clock.speed = 100;
// 创建按钮控制时间document.getElementById('morningBtn').addEventListener('click', () => { engine.clock.currentTime = new Date('2025-05-15 08:00:00');});
document.getElementById('noonBtn').addEventListener('click', () => { engine.clock.currentTime = new Date('2025-05-15 12:00:00');});
document.getElementById('eveningBtn').addEventListener('click', () => { engine.clock.currentTime = new Date('2025-05-15 18:00:00');});
document.getElementById('nightBtn').addEventListener('click', () => { engine.clock.currentTime = new Date('2025-05-15 22:00:00');});
复制代码


我的感受:写一个完整的示例,把学到的都用上,感觉很有成就感!


我的发现


  • 可以设置初始时间

  • 可以让时间自动流逝

  • 可以控制时间流速

  • 可以手动切换时间


虽然代码还很简单,但是已经能做出一个基本的时间控制系统了!

第十四步:踩过的坑

作为一个初学者,我踩了不少坑,记录下来避免再犯:

坑 1:设置了时间但没效果

原因:没有添加动态天空,或者没有开启循环渲染。


解决


  1. 确保添加了 DynamicSky

  2. 确保开启了 enableAnimationLoop

坑 2:时间不自动流逝

原因:没有设置 tickMode,或者没有开启循环渲染。


解决


  1. 设置 engine.clock.tickMode = engine.clock.TICK_NORMAL

  2. 确保开启了 enableAnimationLoop

坑 3:时间流逝太快或太慢

原因speed 值设置不合适。


解决:根据需求调整 speed 值,一般 1-1000 之间比较合适。

坑 4:日期格式写错了

原因new Date() 的格式写错了。


解决:格式必须是 '年-月-日 时:分:秒',比如 '2025-05-15 14:00:00'

坑 5:设置了起止时间但没效果

原因:没有设置 tickModeTICK_LOOPTICK_CLAMP


解决:起止时间只在 TICK_LOOPTICK_CLAMP 模式下生效,需要设置对应的模式。

坑 6:时区设置不对

原因:时区偏移量设置错误。


解决:时区偏移量是相对于 UTC 的小时数,东八区是 8,西五区是 -5。

我的学习总结

经过这一天的学习,我掌握了:


  1. 时间系统的作用:控制场景时间,影响动态天空、光照等效果

  2. 如何设置时间:通过 engine.clock.currentTime 设置

  3. 四种时钟模式

  4. TICK_NONE:时间不自动流逝

  5. TICK_NORMAL:时间正常自动流逝

  6. TICK_LOOP:时间在起止时间之间循环

  7. TICK_CLAMP:时间限制在起止时间之间

  8. 如何控制时间流速:通过 engine.clock.speed 控制

  9. 起止时间的设置:通过 startTimestopTime 限制时间范围

  10. 时区设置:通过 timeZoneOffset 设置时区偏移

  11. UTC 时间:通过 currentTimeUTC 获取或设置 UTC 时间

  12. 重置时钟:通过 reset() 方法重置到开始时间

  13. 与动态天空的配合:时间系统控制时间,动态天空根据时间渲染效果


我的感受:时间系统真的很强大!虽然概念有点抽象,但是用起来其实不难。关键是要理解时间系统和动态天空的关系,它们配合使用才能实现完整的昼夜交替效果!


下一步计划


  1. 学习更多动态天空的配置选项

  2. 尝试创建时间切换的动画效果

  3. 做一个完整的时间演示项目




学习笔记就到这里啦!作为一个初学者,我觉得时间系统虽然概念有点抽象,但是用起来其实不难。关键是要理解时间系统和动态天空的关系,它们配合使用才能实现完整的昼夜交替效果!希望我的笔记能帮到其他初学者!大家一起加油!

用户头像

map_3d_vis

关注

还未添加个人签名 2025-11-17 加入

还未添加个人简介

评论

发布
暂无评论
JSAPIThree 时间系统学习笔记:让场景随时间变化_学习笔记_map_3d_vis_InfoQ写作社区