了解Threejs中的Clock對象以及簡單應用


什么是Clock對象

如果你對 JavaScript 有一定了解,那么 JavaScript 的時間對象 Date 你一定不陌生,Clock 本質上就是對 Date 進行封裝,提供了一些方法和屬性

當你通過 Threejs 編寫一些和時間相關程序時候,不用在對 Date 進行封裝,直接調用 Clock 對象的方法和屬性即可

Clock對象的主要屬性和方法

  • 屬性.autoStart,Boolean,默認值是true,如果設置為true,則在第一次update 時開啟時鍾 Clock
  • 屬性.startTime ,Float,存儲時鍾 Clock 最后一次調用.start(), .getElapsedTime().getDelta()方法的時間
  • 屬性.elapsedTime ,Float,保存時鍾 Clock 運行的總時長
  • 屬性.running ,Boolean,判斷時鍾 Clock 是否在運行
  • 方法.start(),啟動時鍾,同時將startTimeoldTime設置為當前時間,設置elapsedTime為 0,並且設置runningtrue
  • 方法.stop(),停止時鍾,同時將oldTime設置為當前時間
  • 方法.getElapsedTime(),獲取自時鍾啟動后的秒數,摒棄將oldTime設置為當前時間,如果autoStart設置為true且時鍾並未運行,則該方法同時啟動時鍾
  • 方法.getDelta(),獲取自oldTime設置后到當前的秒數,同時將oldTime設置為當前時間,如果autoStart設置為true且時鍾並未運行,則該方法同時啟動時鍾

常用方法:getDelta()

  • 獲得前后兩次執行該方法的時間間隔
  • 假設你執行一次.getDelta ()方法,再執行一次.getDelta ()方法,第二次執行.getDelta ()方法時候,可以返回上次調用該方法到本次調用之間的時間間隔,返回間隔時間單位是秒

簡單的應用場景:對 Threejs 渲染方式的理解

  • Threejs渲染器的渲染方法.render()每執行一次就得到一幀圖像,渲染效果也就是圖像會顯示在 Canvas 畫布上
  • 如果一個三維場景是不停變化的,肯定要周期性調用執行.render()方法,更新canvas畫布顯示內容,一幀幀圖像隨着時間變化,這樣就展現出來一個動畫效果
  • 為了周期性執行渲染器渲染方法.render(),一般通過瀏覽器的APIwindow.requestAnimationFrame實現,瀏覽器會控制渲染頻率
  • 一般性能理想的情況下,每秒s渲染60次左右,在實際的項目中,如果需要渲染的場景比較復雜,一般都會低於60,也就是渲染的兩幀時間間隔大於16.67ms
  • 代碼示例:
// 創建一個時鍾對象Clock
var clock = new THREE.Clock();
// 創建渲染函數
function render() {
	//執行渲染方法,渲染出來一幀圖像
	renderer.render(scene, camera);
	
	//周期性執行渲染函數
	requestAnimationFrame(render);
	
	//clock.getDelta()方法獲得兩幀的時間間隔,返回時間單位:秒
	var T = clock.getDelta();
	
	console.log('兩幀渲染時間間隔',T*1000+'毫秒');
	console.log('查看每秒渲染頻率',1/T);
}
render();

關於requestAnimationFrame()方法

  • window.requestAnimationFrame(callback)告訴瀏覽器——你希望執行一個動畫,並且要求瀏覽器在下次重繪之前調用指定的回調函數更新動畫
  • 該方法需要傳入一個回調函數作為參數,該回調函數會在瀏覽器下一次重繪之前執行
  • 當你准備更新動畫時你應該調用此方法,這將使瀏覽器在下一次重繪之前調用你傳入給該方法的動畫函數(即你的回調函數)
  • 回調函數執行次數通常是每秒60次,但在大多數遵循W3C建議的瀏覽器中,回調函數執行次數通常與瀏覽器屏幕刷新次數相匹配
  • 為了提高性能和電池壽命,因此在大多數瀏覽器里,當requestAnimationFrame()運行在后台標簽頁或者隱藏的<iframe>里時,requestAnimationFrame()會被暫停調用以提升性能和電池壽命
  • 參數

    callback,下一次重繪之前更新動畫幀所調用的函數(即上面所說的回調函數)
    該回調函數會被傳入DOMHighResTimeStamp參數,該參數與performance.now()的返回值相同,它表示requestAnimationFrame()開始去執行回調函數的時刻

  • 返回值

    一個long整數,請求 ID,是回調列表中唯一的標識
    是個非零值,沒別的意義,你可以傳這個值給window.cancelAnimationFrame()以取消回調函數

使用setInterval()requestAnimationFrame()方法繪制的優劣

  • 當然使用setInterval()方法可以實現動畫效果但是,setInterval()方法有一定的缺點

    setInterval()方法,不考慮瀏覽器中發生的事情,如果你正在瀏覽其他頁面,這個函數仍然會每隔幾毫秒就會被調用一次,
    除此之外,setInterval()方法並沒有跟顯示器的重畫同步,着可能會導致較高的CPU使用,降低系統效率。 —《Three.js 開發指南》

  • 使用requestAnimationFrame()函數即可解決上述問題,詳情看上方requestAnimationFrame()函數描述,這個函數的時間間隔是瀏覽器定義的,我們可以在指定的函數里面實現繪畫操作

在vue中使用requestAnimationFrame()方法

一定要傳入函數名而不是帶上立即執行符號,如requestAnimationFrame(this.animate)即可

參考文檔 ———— Three.js Clock

我是 fx67ll.com,如果您發現本文有什么錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~ 😃
轉發請注明參考文章地址,非常感謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM