/*global document, window */
/**
* Creates a new FPSDisplay object.
*
* Use this class to create a field at the
* top of the browser that displays the current
* frames per second and total number of elements
* in an optional passed array.
*
* Note: FPSDisplay will not function in browsers
* whose Date object does not support Date.now().
* These include IE6, IE7, and IE8.
*
* @constructor
*/
function FPSDisplay() {}
/**
* Name
* @type {string}
* @memberof FPSDisplay
*/
FPSDisplay.name = 'FPSDisplay';
/**
* Set to false to stop requesting animation frames.
* @type {boolean}
* @memberof FPSDisplay
*/
FPSDisplay.active = false;
/**
* Frames per second.
* @type {number}
* @memberof FPSDisplay
*/
FPSDisplay.fps = 0;
/**
* Total items.
* @type {number}
* @memberof FPSDisplay
*/
FPSDisplay.totalItems = 0;
/**
* The current time.
* @type {number}
* @private
* @memberof FPSDisplay
*/
FPSDisplay._time = Date.now();
/**
* The time at the last frame.
* @type {number}
* @private
* @memberof FPSDisplay
*/
FPSDisplay._timeLastFrame = FPSDisplay._time;
/**
* The time the last second was sampled.
* @type {number}
* @private
* @memberof FPSDisplay
*/
FPSDisplay._timeLastSecond = FPSDisplay._time;
/**
* Holds the total number of frames
* between seconds.
* @type {number}
* @private
* @memberof FPSDisplay
*/
FPSDisplay._frameCount = 0;
/**
* Initializes the FPSDisplay.
* @function update
* @memberof FPSDisplay
*/
FPSDisplay.init = function() {
if (this.el) { // should only create one instance of FPSDisplay.
return;
}
this.active = true;
/**
* A reference to the DOM element containing the display.
* @private
*/
this.el = document.createElement('div');
this.el.id = 'FPSDisplay';
this.el.className = 'fpsDisplay';
this.el.style.backgroundColor = 'black';
this.el.style.color = 'white';
this.el.style.fontFamily = 'Helvetica';
this.el.style.padding = '0.5em';
this.el.style.opacity = '0.5';
this.el.style.position = 'fixed';
this.el.style.top = 0;
this.el.style.right = 0;
this.el.style.left = 0;
this.el.style.zIndex = 1000;
// create totol elements label
var labelContainer = document.createElement('span');
labelContainer.className = 'fpsDisplayLabel';
labelContainer.style.marginLeft = '0.5em';
label = document.createTextNode('total elements: ');
labelContainer.appendChild(label);
this.el.appendChild(labelContainer);
// create textNode for totalElements
this.totalElementsValue = document.createTextNode('0');
this.el.appendChild(this.totalElementsValue);
// create fps label
labelContainer = document.createElement('span');
labelContainer.className = 'fpsDisplayLabel';
labelContainer.style.marginLeft = '0.5em';
var label = document.createTextNode('fps: ');
labelContainer.appendChild(label);
this.el.appendChild(labelContainer);
// create textNode for fps
this.fpsValue = document.createTextNode('0');
this.el.appendChild(this.fpsValue);
document.body.appendChild(this.el);
};
/**
* If 1000ms have elapsed since the last evaluated second,
* fps is assigned the total number of frames rendered and
* its corresponding textNode is updated. The total number of
* elements is also updated.
*
* @function update
* @memberof FPSDisplay
* @param {Number} [opt_totalItems] The total items in the system.
*/
FPSDisplay.update = function(opt_totalItems) {
this.totalItems = opt_totalItems || 0;
this._time = Date.now();
this._frameCount++;
// at least a second has passed
if (this._time > this._timeLastSecond + 1000) {
this.fps = this._frameCount;
this._timeLastSecond = this._time;
this._frameCount = 0;
this.fpsValue.nodeValue = this.fps;
this.totalElementsValue.nodeValue = this.totalItems;
}
};
/**
* Hides FPSDisplay from DOM.
* @function hide
* @memberof FPSDisplay
*/
FPSDisplay.hide = function() {
this.el.style.display = 'none';
FPSDisplay.active = false;
};
/**
* Shows FPSDisplay from DOM.
* @function show
* @memberof FPSDisplay
*/
FPSDisplay.show = function() {
this.el.style.display = 'block';
FPSDisplay.active = true;
};
module.exports = FPSDisplay;