作為一個剛開始學習 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;
我的發現:
- 如果當前時間在範圍內,時間會正常流逝
- 如果使用
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:00speed:時間流速倍率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:設置了時間但沒效果
原因:沒有添加動態天空,或者沒有開啓循環渲染。
解決:
- 確保添加了
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()方法重置到開始時間 - 與動態天空的配合:時間系統控制時間,動態天空根據時間渲染效果
我的感受:時間系統真的很強大!雖然概念有點抽象,但是用起來其實不難。關鍵是要理解時間系統和動態天空的關係,它們配合使用才能實現完整的晝夜交替效果!
下一步計劃:
- 學習更多動態天空的配置選項
- 嘗試創建時間切換的動畫效果
- 做一個完整的時間演示項目
學習筆記就到這裏啦!作為一個初學者,我覺得時間系統雖然概念有點抽象,但是用起來其實不難。關鍵是要理解時間系統和動態天空的關係,它們配合使用才能實現完整的晝夜交替效果!希望我的筆記能幫到其他初學者!大家一起加油!