楼主: 斗转星移哦
39 0

[战略与规划] JSAPIThree 时间系统学习笔记:让场景随时间变化 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-6-22
最后登录
2018-6-22

楼主
斗转星移哦 发表于 2025-11-21 22:45:53 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

作为一个刚接触 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');

我的观察:此时天空呈现明亮的蓝色,光照强烈,完全还原了真实白天的视觉感受。

我的理解:使用 JavaScript 的 Date 构造函数即可创建精确的时间点。

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
来配置时钟的行为方式,共有四种模式可供选择:

模式一:TICK_NONE(静态模式)

engine.clock.tickMode = engine.clock.TICK_NONE;

我的理解:在此模式下,时间不会自行推进,必须由开发者手动设置 currentTime 才能改变时间状态。这也是系统的默认行为。

我的尝试:

engine.clock.tickMode = engine.clock.TICK_NONE;
engine.clock.currentTime = new Date('2025-05-15 10:00:00');
// 设置初始时间
engine.clock.currentTime = new Date('2025-05-15 06:00:00');

// 开启时间自动流逝(正常模式)
engine.clock.tickMode = engine.clock.TICK_NORMAL;

我的发现

时间开始自动流动!天空色彩与光照随之动态演变,完整呈现从清晨日出、正午阳光、黄昏晚霞到夜幕降临的全过程,并持续向前推进,不会重复循环。

我的感受

效果非常震撼,如同观看一段延时摄影视频,能够直观感受到昼夜更替的自然节奏。

重要提示

若希望时间自动更新,必须启用渲染循环功能,否则时间状态将保持静止。

enableAnimationLoop

模式一:TICK_PAUSE(暂停模式)

engine.clock.tickMode = engine.clock.TICK_PAUSE;

我的理解

在此模式下,时间处于冻结状态,不会自行推进。适用于需要手动控制或精确调试时间点的应用场景。

模式二:TICK_NORMAL(正常模式)

engine.clock.tickMode = engine.clock.TICK_NORMAL;

我的理解

时间按照真实世界节奏连续运行,不受起始和结束时间限制,无限向前延伸。

模式三: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');

// 初始化当前时间为上午10点
engine.clock.currentTime = new Date('2025-05-15 10:00:00');

// 启用循环模式
engine.clock.tickMode = engine.clock.TICK_LOOP;

我的发现

时间在 06:00 至 22:00 之间不断循环。每当到达 22:00,系统立即返回至 06:00 并继续运行。

我的想法

该模式非常适合用于演示用途,可反复展示一天内的光影变化过程,提升可视化表达效果。

模式四:TICK_CLAMP(钳制模式)

engine.clock.tickMode = engine.clock.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');

// 初始时间设为上午10点
engine.clock.currentTime = new Date('2025-05-15 10:00:00');

// 激活钳制模式
engine.clock.tickMode = engine.clock.TICK_CLAMP;

我的发现

时间从 06: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');

我的理解

通过设置开始与停止时间,可以划定一个合法的时间段。这一设定通常配合循环或钳制模式使用,以实现对时间流动范围的有效控制。

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;

我的观察

当前时间若处于设定范围内,时间将正常推进。
若采用

TICK_LOOP
模式,在达到停止时间后会自动跳转回开始时间,实现循环。
若采用
TICK_CLAMP
模式,则在抵达停止时间后,时间流将完全停止。

我的思考

这种机制可以精准限定时间展示区间,例如仅模拟白天时段的变化过程!

第六步:调节时间流逝速度

观察到时间能够自动运行后,我产生了新的疑问:是否可以调整时间流动的快慢?

根据文档说明,可通过

engine.clock.speed
参数来控制时间流速。

// 调整时间流速倍率
engine.clock.speed = 1000; // 设为1000倍速

我的理解

speed
表示时间加速的倍数。默认值为1,代表真实时间速度;设置为1000则表示时间以千倍速前进,极大压缩实际耗时。

我的测试案例

// 正常速度
engine.clock.speed = 1;

// 十倍速
engine.clock.speed = 10;

// 百倍速
engine.clock.speed = 100;

// 千倍速(极快)
engine.clock.speed = 1000;

我的观察结果

  • speed = 1
    :时间缓慢推进,适合细节观察。
  • speed = 100
    :时间明显加快,变化可见但不过于迅速。
  • speed = 1000
    :时间飞速流逝,几分钟内即可浏览一整天的动态。

我的设想

在进行场景演示时,使用较高的 speed 值可快速呈现昼夜更替效果,提升展示效率。

第七步:重置时钟状态

随着时间持续流动,我想到一个问题:能否将时间重新归零?

文档指出,可调用

reset()
方法实现时钟重置。

// 将时钟恢复至初始状态
engine.clock.reset();

我的理解

执行

reset()
后,当前时间会被设为
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();

// 输出验证结果
console.log(engine.clock.currentTime); // 显示为 2025-05-15 06:00:00

我的发现

重置后,currentTime 成功返回到预设的开始时间,相当于时间线重新启动。

我的想法

在做交互式演示时,利用 reset 功能可以让动画或模拟过程一键回到初始状态,增强用户体验。

第八步:引入 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;

我的理解

timeZoneOffset 的单位是小时,表示相对于 UTC 的偏移量。
例如,北京时间为 UTC+8,对应值为 +8;纽约时间为 UTC-5,对应值为 -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 时间与本地时间进行转换处理。这意味着时间显示能够根据设定的时区正确反映实际区域时间。

这一特性启发我思考:若开发面向全球用户的应用,完全可以通过动态调整时区偏移来适配不同地区的本地时间需求,从而实现更精准的时间展示逻辑。

时间系统与动态天空的联动效果

根据官方文档说明,时间系统的设置主要服务于动态天空(DynamicSky)的视觉表现。以下为实际测试代码:


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 属性了解加深,我尝试是否能在创建引擎实例的同时完成时钟设置。查阅文档确认支持通过初始化选项传入 clock 配置:

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 模式
    timeZoneOffset: 8
  }
});

这种方式的优势在于:所有时间相关设置集中声明,避免后续重复赋值,提升代码可读性与维护效率。

各 clock 参数含义解析

currentTime
表示当前模拟时间点,默认情况下若未指定,则使用当天上午 10:00:00。
speed
定义时间流动速度的倍率,数值越大时间流逝越快。
startTime
设定时间循环或播放的起始时刻,未设置时默认取当前系统时间。
stopTime
设定时间终止点,常用于限制动画播放区间,未设置则默认为当前时间。
tickMode
控制时间推进方式,例如一次性前进或循环播放等行为模式。
timeZoneOffset
用于调整相对于 UTC 的时区偏移量(单位为小时),便于匹配目标地区标准时间。

简化配置示例

以下为一个精简但实用的初始化配置:


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 // 设置为循环模式
  }
});

结果表明:所有时间参数均可在初始化时一并设定,大幅减少后期调用,使主流程更加清晰简洁。

典型应用场景设想

掌握时间控制系统后,我开始探索其在真实项目中的潜在用途。

场景一:分时段数据可视化展示

可用于呈现城市交通流量、人流热度等随时间变化的数据分布。例如:

  • 早上 8 点:加载并展示早高峰出行数据;
  • 中午 12 点:切换为午间活动热点图;
  • 晚上 8 点:显示夜间消费或照明情况。

实现方式如下:


// 切换至早晨时段
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();

通过手动设定时间点,结合回调函数触发对应数据层的显示,可构建出具有时间维度交互感的可视化应用。

我的想法:通过展示不同时段的数据变化,用户能够更加直观地观察到场景的动态演变过程。

场景一:实现夜间数据可视化

为了呈现夜晚时段的信息状态,我调用了以下函数:

showNightData();

这样可以清晰展现特定时间下的数据分布,增强用户的感知体验。

场景二:构建全天候时间流转演示

我希望创建一个自动播放的功能,模拟从清晨到深夜的完整过程。具体实现如下:

  • 将初始时间设定为早上6点:
engine.clock.currentTime = new Date('2025-05-15 06:00:00');
  • 开启正常模式的时间流动,并设置为100倍速:
engine.clock.tickMode = engine.clock.TICK_NORMAL;
engine.clock.speed = 100;
DynamicSky

这一设计使得观众能在短时间内感受昼夜更替的视觉冲击,提升演示效果。

场景三:同步现实世界时间

为了让虚拟场景与真实时间保持一致,我进行了如下配置:

  • 获取当前系统时间作为初始值:
engine.clock.currentTime = new Date();
  • 启用自然流逝模式,速度设为1倍:
engine.clock.tickMode = engine.clock.TICK_NORMAL;
engine.clock.speed = 1;
enableAnimationLoop

如此一来,用户所见即为现实中对应时刻的场景表现,增强了沉浸感和真实性。

综合实践:整合知识完成完整示例

在掌握上述技巧后,我编写了一个集大成的完整案例,融合了所有学到的内容:

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');
});
tickMode

通过这个综合性项目,我成功实现了时间控制的核心功能,收获了极大的成就感。

核心发现总结

在实践过程中,我逐步掌握了以下几个关键点:

  • 可自定义初始时间点
  • 支持时间自动推进
  • 灵活调节时间流速
  • 允许通过交互操作手动切换时间

尽管代码结构尚简,但已具备基础的时间管理系统雏形,具备良好的扩展潜力。

常见问题与避坑指南

作为初学者,在开发过程中遇到了一些典型问题,现记录如下以便后续规避:

问题一:时间设置无效

原因分析:未引入动态天空组件或未启动动画循环渲染机制。

解决方案

  • 确认已添加动态天空对象
  • 确保启用了循环渲染功能
engine.clock.tickMode = engine.clock.TICK_NORMAL

问题二:时间无法自动前进

原因分析:未正确设置时间步进模式,或动画循环未开启。

解决方案

  • 明确指定 tickMode 为 TICK_NORMAL 模式
  • 检查并启用渲染循环

问题三:时间流逝节奏异常

原因分析speed 参数数值设置不合理。

解决方案:根据实际需求调整 speed 值,推荐范围为 1 至 1000 之间,以获得平滑过渡效果。

问题四:日期格式错误导致解析失败

原因分析:传入的日期字符串不符合标准格式要求。

解决方案:严格遵循合法的时间格式规范,例如使用 'YYYY-MM-DD HH:mm:ss' 格式进行输入,如 '2025-05-15 08:00:00'。

new Date()
'年-月-日 时:分:秒'
'2025-05-15 14:00:00'

问题五:设定起止时间无反应

原因分析:未将时间模式设置为支持区间播放的状态。

解决方案:必须将 tickMode 设置为 TICK_INTERVAL 或 TICK_PLAYBACK 模式,起止时间控制才生效。

speed
TICK_LOOP
TICK_CLAMP

在不同的时钟模式下,时间系统的行为会有所不同,因此需要正确配置相应的模式以确保功能正常生效。

常见问题:时区设置错误
问题原因:时区偏移量配置不准确。
解决方案:时区偏移量应根据与 UTC 的小时差进行设置。例如,东八区对应 +8,西五区则为 -5。

timeZoneOffset

学习成果总结

通过本次学习,我掌握了以下核心知识点:

  • 时间系统的用途:用于控制场景中的时间变化,进而影响动态天空、光照等视觉效果。
  • 时间的设定方法
    engine.clock.currentTime
  • 四种时钟模式的特点
    • TICK_NONE
      :时间静止,不会自动推进。
    • TICK_NORMAL
      :时间按正常速度自动运行。
    • TICK_LOOP
      :时间在设定的起始与结束时间之间循环播放。
    • TICK_CLAMP
      :时间被限制在指定范围内,到达终点后停止。
  • 时间流速的调节:可通过以下方式控制时间流逝速度:
    engine.clock.speed
  • 时间范围的设定:使用以下两个参数来定义时间区间:
    startTime
    stopTime
  • UTC 时间的操作:支持获取或设置协调世界时(UTC):
    currentTimeUTC
  • 时钟重置功能:可通过特定方法将时间恢复至初始状态:
    reset()
  • 与动态天空的联动机制:时间系统驱动时间变化,动态天空依据当前时间渲染对应的环境效果。

个人体会

时间系统具备强大的控制能力。尽管初学时概念略显抽象,但实际操作起来并不复杂。关键在于理解时间系统与动态天空之间的协同关系——只有两者结合使用,才能实现完整的昼夜更替效果。

后续学习计划

  • 深入探索动态天空的各项配置参数
  • 尝试制作基于时间变换的动画过渡效果
  • 开发一个完整的时间演示项目,整合所学知识

以上是我的学习记录。作为一名初学者,我认为只要理清逻辑,掌握时间系统并非难事。希望这份笔记能为其他刚入门的朋友提供帮助!共同进步,一起努力!

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Three 学习笔记 系统学习 时间变化 SAP

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-5 20:18