什么是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()
,啟動時鍾,同時將startTime
和oldTime
設置為當前時間,設置elapsedTime
為 0,並且設置running
為true
- 方法
.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)
即可
我是 fx67ll.com,如果您發現本文有什么錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~ 😃
轉發請注明參考文章地址,非常感謝!!!