博客 / 詳情

返回

JSAPIThree 時間系統學習筆記:讓場景隨時間變化

作為一個剛開始學習 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. 四種時鐘模式

    • TICK_NONE:時間不自動流逝
    • TICK_NORMAL:時間正常自動流逝
    • TICK_LOOP:時間在起止時間之間循環
    • TICK_CLAMP:時間限制在起止時間之間
  4. 如何控制時間流速:通過 engine.clock.speed 控制
  5. 起止時間的設置:通過 startTimestopTime 限制時間範圍
  6. 時區設置:通過 timeZoneOffset 設置時區偏移
  7. UTC 時間:通過 currentTimeUTC 獲取或設置 UTC 時間
  8. 重置時鐘:通過 reset() 方法重置到開始時間
  9. 與動態天空的配合:時間系統控制時間,動態天空根據時間渲染效果

我的感受:時間系統真的很強大!雖然概念有點抽象,但是用起來其實不難。關鍵是要理解時間系統和動態天空的關係,它們配合使用才能實現完整的晝夜交替效果!

下一步計劃

  1. 學習更多動態天空的配置選項
  2. 嘗試創建時間切換的動畫效果
  3. 做一個完整的時間演示項目

學習筆記就到這裏啦!作為一個初學者,我覺得時間系統雖然概念有點抽象,但是用起來其實不難。關鍵是要理解時間系統和動態天空的關係,它們配合使用才能實現完整的晝夜交替效果!希望我的筆記能幫到其他初學者!大家一起加油!
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.