作为一个刚开始学习 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 后会停止,不会继续!
我的想法:这个模式适合需要限制时间范围的场景,比如只展示白天的效果。
第五步:设置起止时间
看到不同的时钟模式后,我开始好奇:startTime 和 stopTime 是怎么用的?
文档说可以设置开始时间和停止时间,用来限制时间的范围!
// 设置开始时间engine.clock.startTime = new Date('2025-05-15 06:00:00');
// 设置停止时间engine.clock.stopTime = new Date('2025-05-15 22:00:00');
复制代码
我的理解:startTime 和 stopTime 定义了时间的范围,配合 TICK_LOOP 或 TICK_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;
复制代码
我的发现:
我的想法:这样就能精确控制时间的范围了,比如只展示白天的时间段!
第六步:控制时间流速
看到时间自动流逝后,我开始好奇:能不能控制时间流逝的速度?
文档说可以通过 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 值,让观众快速看到昼夜交替效果!
第七步:重置时钟
看到时间自动流逝后,我想:能不能重置时间到开始时间?
文档说可以用 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, }});
复制代码
我的发现:可以在初始化时一次性配置所有时钟参数,更方便!
我的理解:
我的尝试:
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:设置了时间但没效果
原因:没有添加动态天空,或者没有开启循环渲染。
解决:
确保添加了 DynamicSky
确保开启了 enableAnimationLoop
坑 2:时间不自动流逝
原因:没有设置 tickMode,或者没有开启循环渲染。
解决:
设置 engine.clock.tickMode = engine.clock.TICK_NORMAL
确保开启了 enableAnimationLoop
坑 3:时间流逝太快或太慢
原因:speed 值设置不合适。
解决:根据需求调整 speed 值,一般 1-1000 之间比较合适。
坑 4:日期格式写错了
原因:new Date() 的格式写错了。
解决:格式必须是 '年-月-日 时:分:秒',比如 '2025-05-15 14:00:00'。
坑 5:设置了起止时间但没效果
原因:没有设置 tickMode 为 TICK_LOOP 或 TICK_CLAMP。
解决:起止时间只在 TICK_LOOP 或 TICK_CLAMP 模式下生效,需要设置对应的模式。
坑 6:时区设置不对
原因:时区偏移量设置错误。
解决:时区偏移量是相对于 UTC 的小时数,东八区是 8,西五区是 -5。
我的学习总结
经过这一天的学习,我掌握了:
时间系统的作用:控制场景时间,影响动态天空、光照等效果
如何设置时间:通过 engine.clock.currentTime 设置
四种时钟模式:
TICK_NONE:时间不自动流逝
TICK_NORMAL:时间正常自动流逝
TICK_LOOP:时间在起止时间之间循环
TICK_CLAMP:时间限制在起止时间之间
如何控制时间流速:通过 engine.clock.speed 控制
起止时间的设置:通过 startTime 和 stopTime 限制时间范围
时区设置:通过 timeZoneOffset 设置时区偏移
UTC 时间:通过 currentTimeUTC 获取或设置 UTC 时间
重置时钟:通过 reset() 方法重置到开始时间
与动态天空的配合:时间系统控制时间,动态天空根据时间渲染效果
我的感受:时间系统真的很强大!虽然概念有点抽象,但是用起来其实不难。关键是要理解时间系统和动态天空的关系,它们配合使用才能实现完整的昼夜交替效果!
下一步计划:
学习更多动态天空的配置选项
尝试创建时间切换的动画效果
做一个完整的时间演示项目
学习笔记就到这里啦!作为一个初学者,我觉得时间系统虽然概念有点抽象,但是用起来其实不难。关键是要理解时间系统和动态天空的关系,它们配合使用才能实现完整的昼夜交替效果!希望我的笔记能帮到其他初学者!大家一起加油!
评论