JsGear — JavaScript版變速齒輪

來源:互聯網
上載者:User

  在JS開發中經常會用到定時器,尤其是一些動畫特效,小遊戲等完全依靠定時器驅動。

  要讓動畫跑得更流暢,我們常常使用較高的重新整理率,例如60fps。由於每一幀的間隔非常短,很難看清楚每一幀具體的運行情況。

  有時整體上看似乎一切良好,但如果放慢定時器的速度,卻會發現其中有部分幀或因代碼裡的小問題,並沒有按我們想象那樣顯示。由於播放的非常快,這些潛在的小問題都掩蓋了。

  為了方便動畫指令碼的觀察和調試,我們嘗試用js模仿一個類似windows下經典的應用程式:變速齒輪,能即時修改系統時鐘的運行頻率!這聽起來似乎很神奇吧~其實原理並不複雜。

  和傳統的變速齒輪運行機制一樣,我們使用鉤子程式勾住預設那幾個定時器相關的API —— setTimeout, setInterval, clearTimeout, clearInterval。當然,所謂的鉤子程式,無非就是預先儲存原來的API引用,接著用自己的程式覆蓋他們。這樣我們就可以攔截之後的定時器調用,然後根據虛擬時鐘的速率,自己維護回調隊列,於是就產生了定時器變速的效果。如果同步上再嚴密點,甚至還可以覆蓋Date對象,讓時間的流逝速度都隨之而變!

  當然,有不少問題仍然難以解決的。

  時鐘頻率被加快後,每一幀的時間間隔被大幅縮短,甚至小於1ms。而js定時器頻率眾所周知,遠達不到這樣的精度。於是只能用“跳幀”來解決這個問題。例如,一個2ms的定時器,理論上應該每2ms觸發一次,但某個瀏覽器最短只支援16ms的間隔,那麼每次定時器觸發內迴圈調用 16/2 = 8次回調,來彌補頻率上的不足。但由於這8次回調是在同個事件裡一口氣執行的,所以前7次的介面操作都不會立即渲染出來,只有第8次的操作才會有所表現,所以就有了“跳”的感覺。

  但是這個方法只能解決 setInterval 的定時器,因為它的時間間隔以及回調都是固定的。對於 setTimeout 這樣每次延時不確定的,甚至還無法確定下一幀是否接著運行,跳幀機制就有些無從為力了。

  不過只實現一個準系統的還是比較容易的:

  JsGear,就是根據這個思路實現的 JavaScript 變速齒輪外掛程式,對時間相關的API都進行了嚴密的封裝。因為它完全是用js/css製作的,所以不依賴任何外掛程式,引入頁面就可以使用。

  為了讓使用更快捷,這兩天換了一個新概念的操作介面,並且支援IE6+, FireFox, Chrome, Safari, Opera瀏覽器,以及Quirks模式。

  測試Demo:  http://www.etherdream.com/JSGear/demo.html

 

  

  

  在自己的頁面裡測試很簡單,把jsgear.js插入到所有的指令碼之前就可以。這裡上傳了一份到部落格附件裡,複製下面代碼到自己的頁面內即可使用:

  <scrpt src="http://files.cnblogs.com/jsapp/jsgear.js"></script>

  

  當然,目前還只是示範版本,實現了準系統,還有不少小問題。大家要是有什麼好多思路和建議,歡迎探討。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.