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