1 2 /** 3 * @class Ticker是一个定时器类。它可以按指定帧率重复运行,从而按计划执行代码。 4 * @param {Number} fps 指定定时器的运行帧率。 5 * @module hilo/util/Ticker 6 * @requires hilo/core/Class 7 * @requires hilo/core/Hilo 8 */ 9 var Ticker = Class.create(/** @lends Ticker.prototype */{ 10 constructor: function Ticker(fps){ 11 this._targetFPS = fps || 30; 12 this._interval = 1000 / this._targetFPS; 13 this._tickers = []; 14 }, 15 16 _paused: false, 17 _targetFPS: 0, 18 _interval: 0, 19 _intervalId: null, 20 _tickers: null, 21 _lastTime: 0, 22 _tickCount: 0, 23 _tickTime: 0, 24 _measuredFPS: 0, 25 26 /** 27 * 启动定时器。 28 * @param {Boolean} userRAF 是否使用requestAnimationFrame,默认为false。 29 */ 30 start: function(useRAF){ 31 if(this._intervalId) return; 32 this._lastTime = +new Date(); 33 34 var self = this, interval = this._interval, 35 raf = window.requestAnimationFrame || 36 window[Hilo.browser.jsVendor + 'RequestAnimationFrame']; 37 38 if(useRAF && raf){ 39 var tick = function(){ 40 self._tick(); 41 } 42 var runLoop = function(){ 43 self._intervalId = setTimeout(runLoop, interval); 44 raf(tick); 45 }; 46 }else{ 47 runLoop = function(){ 48 self._intervalId = setTimeout(runLoop, interval); 49 self._tick(); 50 }; 51 } 52 53 runLoop(); 54 }, 55 56 /** 57 * 停止定时器。 58 */ 59 stop: function(){ 60 clearTimeout(this._intervalId); 61 this._intervalId = null; 62 this._lastTime = 0; 63 }, 64 65 /** 66 * 暂停定时器。 67 */ 68 pause: function(){ 69 this._paused = true; 70 }, 71 72 /** 73 * 恢复定时器。 74 */ 75 resume: function(){ 76 this._paused = false; 77 }, 78 79 /** 80 * @private 81 */ 82 _tick: function(){ 83 if(this._paused) return; 84 var startTime = +new Date(), 85 deltaTime = startTime - this._lastTime, 86 tickers = this._tickers; 87 88 for(var i = 0, len = tickers.length; i < len; i++){ 89 tickers[i].tick(deltaTime); 90 } 91 92 //calculates the real fps 93 var endTime = +new Date(); 94 if(++this._tickCount >= this._targetFPS){ 95 this._measuredFPS = 1000 / (this._tickTime / this._tickCount) + 0.5 >> 0; 96 this._tickCount = 0; 97 this._tickTime = 0; 98 }else{ 99 this._tickTime += endTime - this._lastTime; 100 } 101 this._lastTime = endTime; 102 }, 103 104 /** 105 * 获得测定的运行时帧率。 106 */ 107 getMeasuredFPS: function(){ 108 return this._measuredFPS; 109 }, 110 111 /** 112 * 添加定时器对象。定时器对象必须实现 tick 方法。 113 * @param {Object} tickObject 要添加的定时器对象。此对象必须包含 tick 方法。 114 */ 115 addTick: function(tickObject){ 116 if(!tickObject || typeof(tickObject.tick) != 'function'){ 117 throw new Error('Ticker: The tick object must implement the tick method.'); 118 } 119 this._tickers.push(tickObject); 120 }, 121 122 /** 123 * 删除定时器对象。 124 * @param {Object} tickObject 要删除的定时器对象。 125 */ 126 removeTick: function(tickObject){ 127 var tickers = this._tickers, 128 index = tickers.indexOf(tickObject); 129 if(index >= 0){ 130 tickers.splice(index, 1); 131 } 132 } 133 134 });