Refactored public dirs

This commit is contained in:
Paul Graffam 2019-01-29 16:54:10 -05:00
parent ea9380baa5
commit 98ced74b80
9 changed files with 778 additions and 97 deletions

View File

@ -1,87 +0,0 @@
.alarm{
color: #b70000;
text-shadow: 0 0 0 #b70000,
0 0 1px #fff,
0 0 1px #fff,
0 0 2px #fff,
0 0 2px #fff,
0 0 3px #fff,
0 0 3px #fff,
0 0 4px #fff,
0 0 4px #fff;
}
.rs-base{
position: absolute;
z-index: 10000;
padding: 10px;
background-color: #222;
font-size: 10px;
line-height: 1.2em;
width: 350px;
font-family: 'Roboto Condensed', tahoma, sans-serif;
left: 0;
top: 0;
overflow: hidden;
}
.rs-base h1{
margin: 0;
padding: 0;
font-size: 1.4em;
color: #fff;
margin-bottom: 5px;
cursor: pointer;
}
.rs-base div.rs-group{
margin-bottom: 10px;
}
.rs-base div.rs-group.hidden{
display: none;
}
.rs-base div.rs-fraction{
position: relative;
margin-bottom: 5px;
}
.rs-base div.rs-fraction p{
width: 120px;
text-align: right;
margin: 0;
padding: 0;
}
.rs-base div.rs-legend{
position: absolute;
line-height: 1em;
}
.rs-base div.rs-counter-base{
position: relative;
margin: 2px 0;
height: 1em;
color: white;
}
.rs-base span.rs-counter-id{
position: absolute;
left: 0;
top: 0;
}
.rs-base div.rs-counter-value{
position: absolute;
left: 90px;
width: 30px;
height: 1em;
top: 0;
text-align: right;
}
.rs-base canvas.rs-canvas{
position: absolute;
right: 0;
}

View File

@ -74,3 +74,4 @@ body {
position: absolute;
top: calc(50% - 8px);
left: calc(50% - 35px); }

View File

@ -3,17 +3,17 @@
<head>
<meta charset="UTF-8">
<title>Three.js Webpack ES6 Boilerplate</title>
<link rel="stylesheet" type="text/css" href="assets/css/app.css">
</head>
<link href="js/../css/main.css" rel="stylesheet"></head>
<body>
<section id="appContainer" class="main">
<div id="loading">Loading...</div>
</section>
<script src="assets/js/rStats.js"></script>
<script src="assets/js/rStats.extras.js"></script>
<script src="assets/js/dat.gui.min.js"></script>
<script type="text/javascript" src="assets/js/app.js"></script><script type="text/javascript" src="assets/js/vendors.app.js"></script><script type="text/javascript" src="assets/js/main.app.js"></script></body>
<script src="js/rStats.js"></script>
<script src="js/rStats.extras.js"></script>
<script src="js/dat.gui.min.js"></script>
<script type="text/javascript" src="js/app.js"></script><script type="text/javascript" src="js/vendors.app.js"></script><script type="text/javascript" src="js/main.app.js"></script></body>
</html>

View File

@ -136,7 +136,7 @@
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "assets/js";
/******/ __webpack_require__.p = "js";
/******/
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);

13
src/public/js/dat.gui.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,16 @@
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["main"],{
/***/ "./src/css/app.scss":
/*!**************************!*\
!*** ./src/css/app.scss ***!
\**************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./src/css/app.scss?");
/***/ }),
/***/ "./src/js/app.js":
/*!***********************!*\
!*** ./src/js/app.js ***!
@ -8,7 +19,7 @@
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data/config */ \"./src/js/data/config.js\");\n/* harmony import */ var _utils_detector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/detector */ \"./src/js/utils/detector.js\");\n/* harmony import */ var _app_main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app/main */ \"./src/js/app/main.js\");\n\n\n // Check environment and set the Config helper\n\nif (true) {\n console.log('----- RUNNING IN DEV ENVIRONMENT! -----');\n _data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].isDev = true;\n}\n\nfunction init() {\n // Check for webGL capabilities\n if (!_utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].webgl) {\n _utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].addGetWebGLMessage();\n } else {\n var container = document.getElementById('appContainer');\n new _app_main__WEBPACK_IMPORTED_MODULE_2__[\"default\"](container);\n }\n}\n\ninit();\n\n//# sourceURL=webpack:///./src/js/app.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data/config */ \"./src/js/data/config.js\");\n/* harmony import */ var _utils_detector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/detector */ \"./src/js/utils/detector.js\");\n/* harmony import */ var _app_main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app/main */ \"./src/js/app/main.js\");\n/* harmony import */ var _css_app_scss__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./../css/app.scss */ \"./src/css/app.scss\");\n/* harmony import */ var _css_app_scss__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_css_app_scss__WEBPACK_IMPORTED_MODULE_3__);\n\n\n // Styles\n\n // Check environment and set the Config helper\n\nif (true) {\n console.log('----- RUNNING IN DEV ENVIRONMENT! -----');\n _data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].isDev = true;\n}\n\nfunction init() {\n // Check for webGL capabilities\n if (!_utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].webgl) {\n _utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].addGetWebGLMessage();\n } else {\n var container = document.getElementById('appContainer');\n new _app_main__WEBPACK_IMPORTED_MODULE_2__[\"default\"](container);\n }\n}\n\ninit();\n\n//# sourceURL=webpack:///./src/js/app.js?");
/***/ }),
@ -104,7 +115,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Stats; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// Local vars for rStats\nvar rS, bS, glS, tS;\n\nvar Stats =\n/*#__PURE__*/\nfunction () {\n function Stats(renderer) {\n _classCallCheck(this, Stats);\n\n this.renderer = renderer;\n }\n\n _createClass(Stats, [{\n key: \"setUp\",\n value: function setUp() {\n bS = new BrowserStats();\n glS = new glStats();\n tS = new threeStats(this.renderer.threeRenderer);\n rS = new rStats({\n CSSPath: './assets/css/',\n userTimingAPI: true,\n values: {\n frame: {\n caption: 'Total frame time (ms)',\n over: 16,\n average: true,\n avgMs: 100\n },\n fps: {\n caption: 'Framerate (FPS)',\n below: 30\n },\n calls: {\n caption: 'Calls (three.js)',\n over: 3000\n },\n raf: {\n caption: 'Time since last rAF (ms)',\n average: true,\n avgMs: 100\n },\n rstats: {\n caption: 'rStats update (ms)',\n average: true,\n avgMs: 100\n },\n texture: {\n caption: 'GenTex',\n average: true,\n avgMs: 100\n }\n },\n groups: [{\n caption: 'Framerate',\n values: ['fps', 'raf']\n }, {\n caption: 'Frame Budget',\n values: ['frame', 'texture', 'setup', 'render']\n }],\n fractions: [{\n base: 'frame',\n steps: ['texture', 'setup', 'render']\n }],\n plugins: [bS, tS, glS]\n });\n }\n }], [{\n key: \"start\",\n value: function start() {\n rS('frame').start();\n glS.start();\n rS('rAF').tick();\n rS('FPS').frame();\n rS('render').start();\n }\n }, {\n key: \"end\",\n value: function end() {\n rS('render').end(); // render finished\n\n rS('frame').end(); // frame finished\n // Local rStats update\n\n rS('rStats').start();\n rS().update();\n rS('rStats').end();\n }\n }]);\n\n return Stats;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/stats.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Stats; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// Local vars for rStats\nvar rS, bS, glS, tS;\n\nvar Stats =\n/*#__PURE__*/\nfunction () {\n function Stats(renderer) {\n _classCallCheck(this, Stats);\n\n this.renderer = renderer;\n }\n\n _createClass(Stats, [{\n key: \"setUp\",\n value: function setUp() {\n bS = new BrowserStats();\n glS = new glStats();\n tS = new threeStats(this.renderer.threeRenderer);\n rS = new rStats({\n CSSPath: './css/',\n userTimingAPI: true,\n values: {\n frame: {\n caption: 'Total frame time (ms)',\n over: 16,\n average: true,\n avgMs: 100\n },\n fps: {\n caption: 'Framerate (FPS)',\n below: 30\n },\n calls: {\n caption: 'Calls (three.js)',\n over: 3000\n },\n raf: {\n caption: 'Time since last rAF (ms)',\n average: true,\n avgMs: 100\n },\n rstats: {\n caption: 'rStats update (ms)',\n average: true,\n avgMs: 100\n },\n texture: {\n caption: 'GenTex',\n average: true,\n avgMs: 100\n }\n },\n groups: [{\n caption: 'Framerate',\n values: ['fps', 'raf']\n }, {\n caption: 'Frame Budget',\n values: ['frame', 'texture', 'setup', 'render']\n }],\n fractions: [{\n base: 'frame',\n steps: ['texture', 'setup', 'render']\n }],\n plugins: [bS, tS, glS]\n });\n }\n }], [{\n key: \"start\",\n value: function start() {\n rS('frame').start();\n glS.start();\n rS('rAF').tick();\n rS('FPS').frame();\n rS('render').start();\n }\n }, {\n key: \"end\",\n value: function end() {\n rS('render').end(); // render finished\n\n rS('frame').end(); // frame finished\n // Local rStats update\n\n rS('rStats').start();\n rS().update();\n rS('rStats').end();\n }\n }]);\n\n return Stats;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/stats.js?");
/***/ }),

View File

@ -0,0 +1,265 @@
window.glStats = function () {
var _rS = null;
var _totalDrawArraysCalls = 0,
_totalDrawElementsCalls = 0,
_totalUseProgramCalls = 0,
_totalFaces = 0,
_totalVertices = 0,
_totalPoints = 0,
_totalBindTexures = 0;
function _h ( f, c ) {
return function () {
c.apply( this, arguments );
f.apply( this, arguments );
};
}
WebGLRenderingContext.prototype.drawArrays = _h( WebGLRenderingContext.prototype.drawArrays, function () {
_totalDrawArraysCalls++;
if ( arguments[ 0 ] == this.POINTS ) _totalPoints += arguments[ 2 ];
else _totalVertices += arguments[ 2 ];
} );
WebGLRenderingContext.prototype.drawElements = _h( WebGLRenderingContext.prototype.drawElements, function () {
_totalDrawElementsCalls++;
_totalFaces += arguments[ 1 ] / 3;
_totalVertices += arguments[ 1 ];
} );
WebGLRenderingContext.prototype.useProgram = _h( WebGLRenderingContext.prototype.useProgram, function () {
_totalUseProgramCalls++;
} );
WebGLRenderingContext.prototype.bindTexture = _h( WebGLRenderingContext.prototype.bindTexture, function () {
_totalBindTexures++;
} );
var _values = {
allcalls: {
over: 3000,
caption: 'Calls (hook)'
},
drawelements: {
caption: 'drawElements (hook)'
},
drawarrays: {
caption: 'drawArrays (hook)'
}
};
var _groups = [ {
caption: 'WebGL',
values: [ 'allcalls', 'drawelements', 'drawarrays', 'useprogram', 'bindtexture', 'glfaces', 'glvertices', 'glpoints' ]
} ];
var _fractions = [ {
base: 'allcalls',
steps: [ 'drawelements', 'drawarrays' ]
} ];
function _update () {
_rS( 'allcalls' ).set( _totalDrawArraysCalls + _totalDrawElementsCalls );
_rS( 'drawElements' ).set( _totalDrawElementsCalls );
_rS( 'drawArrays' ).set( _totalDrawArraysCalls );
_rS( 'bindTexture' ).set( _totalBindTexures );
_rS( 'useProgram' ).set( _totalUseProgramCalls );
_rS( 'glfaces' ).set( _totalFaces );
_rS( 'glvertices' ).set( _totalVertices );
_rS( 'glpoints' ).set( _totalPoints );
}
function _start () {
_totalDrawArraysCalls = 0;
_totalDrawElementsCalls = 0;
_totalUseProgramCalls = 0;
_totalFaces = 0;
_totalVertices = 0;
_totalPoints = 0;
_totalBindTexures = 0;
}
function _end () {}
function _attach ( r ) {
_rS = r;
}
return {
update: _update,
start: _start,
end: _end,
attach: _attach,
values: _values,
groups: _groups,
fractions: _fractions
};
};
window.threeStats = function ( renderer ) {
var _rS = null;
var _values = {
'renderer.info.memory.geometries': {
caption: 'Geometries'
},
'renderer.info.memory.textures': {
caption: 'Textures'
},
'renderer.info.programs': {
caption: 'Programs'
},
'renderer.info.render.calls': {
caption: 'Calls'
},
'renderer.info.render.faces': {
caption: 'Faces',
over: 1000
},
'renderer.info.render.points': {
caption: 'Points'
},
'renderer.info.render.vertices': {
caption: 'Vertices'
}
};
var _groups = [ {
caption: 'Three.js - Memory',
values: [ 'renderer.info.memory.geometries', 'renderer.info.programs', 'renderer.info.memory.textures' ]
}, {
caption: 'Three.js - Render',
values: [ 'renderer.info.render.calls', 'renderer.info.render.faces', 'renderer.info.render.points', 'renderer.info.render.vertices' ]
} ];
var _fractions = [];
function _update () {
_rS( 'renderer.info.memory.geometries' ).set( renderer.info.memory.geometries );
//_rS( 'renderer.info.programs' ).set( renderer.info.programs.length );
_rS( 'renderer.info.memory.textures' ).set( renderer.info.memory.textures );
_rS( 'renderer.info.render.calls' ).set( renderer.info.render.calls );
_rS( 'renderer.info.render.faces' ).set( renderer.info.render.faces );
_rS( 'renderer.info.render.points' ).set( renderer.info.render.points );
_rS( 'renderer.info.render.vertices' ).set( renderer.info.render.vertices );
}
function _start () {}
function _end () {}
function _attach ( r ) {
_rS = r;
}
return {
update: _update,
start: _start,
end: _end,
attach: _attach,
values: _values,
groups: _groups,
fractions: _fractions
};
};
/*
* From https://github.com/paulirish/memory-stats.js
*/
window.BrowserStats = function () {
var _rS = null;
var _usedJSHeapSize = 0,
_totalJSHeapSize = 0;
var memory = {
usedJSHeapSize: 0,
totalJSHeapSize: 0
};
if ( window.performance && performance.memory )
memory = performance.memory;
if ( memory.totalJSHeapSize === 0 ) {
console.warn( 'totalJSHeapSize === 0... performance.memory is only available in Chrome .' );
}
var _values = {
memory: {
caption: 'Used Memory',
average: true,
avgMs: 1000,
over: 22
},
total: {
caption: 'Total Memory'
}
};
var _groups = [ {
caption: 'Browser',
values: [ 'memory', 'total' ]
} ];
var _fractions = [ {
base: 'total',
steps: [ 'memory' ]
} ];
var log1024 = Math.log( 1024 );
function _size ( v ) {
var precision = 100; //Math.pow(10, 2);
var i = Math.floor( Math.log( v ) / log1024 );
if( v === 0 ) i = 1;
return Math.round( v * precision / Math.pow( 1024, i ) ) / precision; // + ' ' + sizes[i];
}
function _update () {
_usedJSHeapSize = _size( memory.usedJSHeapSize );
_totalJSHeapSize = _size( memory.totalJSHeapSize );
_rS( 'memory' ).set( _usedJSHeapSize );
_rS( 'total' ).set( _totalJSHeapSize );
}
function _start () {
_usedJSHeapSize = 0;
}
function _end () {}
function _attach ( r ) {
_rS = r;
}
return {
update: _update,
start: _start,
end: _end,
attach: _attach,
values: _values,
groups: _groups,
fractions: _fractions
};
};
if (typeof module === 'object') {
module.exports = {
glStats: window.glStats,
threeStats: window.threeStats,
BrowserStats: window.BrowserStats
};
}

478
src/public/js/rStats.js Normal file
View File

@ -0,0 +1,478 @@
// performance.now() polyfill from https://gist.github.com/paulirish/5438650
'use strict';
( function () {
// prepare base perf object
if ( typeof window.performance === 'undefined' ) {
window.performance = {};
}
if ( !window.performance.now ) {
var nowOffset = Date.now();
if ( performance.timing && performance.timing.navigationStart ) {
nowOffset = performance.timing.navigationStart;
}
window.performance.now = function now () {
return Date.now() - nowOffset;
};
}
if( !window.performance.mark ) {
window.performance.mark = function(){}
}
if( !window.performance.measure ) {
window.performance.measure = function(){}
}
} )();
/**
* @class rStats
* @param {rStats~Settings} [settings] Settings for the rStats instance.
*/
/**
* @typedef {Object} rStats~Settings
* @property {Array.<String>} [colours] An array of CSS colour values.
* @property {String} [CSSPath=''] Base URL where rStats.css is located.
* @property {Array.<String>} [css] URLs of CSS or font files to import.
* @property {Object.<String, rStats~CounterProperties>} [values] Properties to use for each counter.
* @property {Array.<Object>} [groups] Define groups of counters.
* @property {Array.<Object>} [fractions] Define stacked counters.
* @property {Array.<Object>} [plugins] Additional plugins.
*/
/**
* @typedef {Object} rStats~CounterProperties
* @property {String} [caption] Caption for this counter.
* @property {Boolean} [average=false] Whether the values should be averaged.
* @property {Number} [avgMs=1000] Duration for which the values should be averaged.
* @property {Number} [below] Value below which the graph should be highlighted.
* @property {Number} [over] Value over which the graph should be highlighted.
* @property {Boolean} [interpolate=true] Whether framerate should be interpolated.
*/
window.rStats = function rStats ( settings ) {
function iterateKeys ( array, callback ) {
var keys = Object.keys( array );
for ( var j = 0, l = keys.length; j < l; j++ ) {
callback( keys[ j ] );
}
}
function importCSS ( url ) {
var element = document.createElement( 'link' );
element.href = url;
element.rel = 'stylesheet';
element.type = 'text/css';
document.getElementsByTagName( 'head' )[ 0 ].appendChild( element );
}
var _settings = settings || {};
var _colours = _settings.colours || [ '#850700', '#c74900', '#fcb300', '#284280', '#4c7c0c' ];
var _cssFont = 'https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700,300';
var _cssRStats = ( _settings.CSSPath ? _settings.CSSPath : '' ) + 'rStats.css';
var _css = _settings.css || [ _cssFont, _cssRStats ];
_css.forEach(function (uri) {
importCSS( uri );
});
if ( !_settings.values ) _settings.values = {};
var _base, _div, _elHeight = 10, _elWidth = 200;
var _perfCounters = {};
function Graph ( _dom, _id, _defArg ) {
var _def = _defArg || {};
var _canvas = document.createElement( 'canvas' ),
_ctx = _canvas.getContext( '2d' ),
_max = 0,
_current = 0;
var c = _def.color ? _def.color : '#666666';
var _dotCanvas = document.createElement( 'canvas' ),
_dotCtx = _dotCanvas.getContext( '2d' );
_dotCanvas.width = 1;
_dotCanvas.height = 2 * _elHeight;
_dotCtx.fillStyle = '#444444';
_dotCtx.fillRect( 0, 0, 1, 2 * _elHeight );
_dotCtx.fillStyle = c;
_dotCtx.fillRect( 0, _elHeight, 1, _elHeight );
_dotCtx.fillStyle = '#ffffff';
_dotCtx.globalAlpha = 0.5;
_dotCtx.fillRect( 0, _elHeight, 1, 1 );
_dotCtx.globalAlpha = 1;
var _alarmCanvas = document.createElement( 'canvas' ),
_alarmCtx = _alarmCanvas.getContext( '2d' );
_alarmCanvas.width = 1;
_alarmCanvas.height = 2 * _elHeight;
_alarmCtx.fillStyle = '#444444';
_alarmCtx.fillRect( 0, 0, 1, 2 * _elHeight );
_alarmCtx.fillStyle = '#b70000';
_alarmCtx.fillRect( 0, _elHeight, 1, _elHeight );
_alarmCtx.globalAlpha = 0.5;
_alarmCtx.fillStyle = '#ffffff';
_alarmCtx.fillRect( 0, _elHeight, 1, 1 );
_alarmCtx.globalAlpha = 1;
function _init () {
_canvas.width = _elWidth;
_canvas.height = _elHeight;
_canvas.style.width = _canvas.width + 'px';
_canvas.style.height = _canvas.height + 'px';
_canvas.className = 'rs-canvas';
_dom.appendChild( _canvas );
_ctx.fillStyle = '#444444';
_ctx.fillRect( 0, 0, _canvas.width, _canvas.height );
}
function _draw ( v, alarm ) {
_current += ( v - _current ) * 0.1;
_max *= 0.99;
if ( _current > _max ) _max = _current;
_ctx.drawImage( _canvas, 1, 0, _canvas.width - 1, _canvas.height, 0, 0, _canvas.width - 1, _canvas.height );
if ( alarm ) {
_ctx.drawImage( _alarmCanvas, _canvas.width - 1, _canvas.height - _current * _canvas.height / _max - _elHeight );
} else {
_ctx.drawImage( _dotCanvas, _canvas.width - 1, _canvas.height - _current * _canvas.height / _max - _elHeight );
}
}
_init();
return {
draw: _draw
};
}
function StackGraph ( _dom, _num ) {
var _canvas = document.createElement( 'canvas' ),
_ctx = _canvas.getContext( '2d' );
function _init () {
_canvas.width = _elWidth;
_canvas.height = _elHeight * _num;
_canvas.style.width = _canvas.width + 'px';
_canvas.style.height = _canvas.height + 'px';
_canvas.className = 'rs-canvas';
_dom.appendChild( _canvas );
_ctx.fillStyle = '#444444';
_ctx.fillRect( 0, 0, _canvas.width, _canvas.height );
}
function _draw ( v ) {
_ctx.drawImage( _canvas, 1, 0, _canvas.width - 1, _canvas.height, 0, 0, _canvas.width - 1, _canvas.height );
var th = 0;
iterateKeys( v, function ( j ) {
var h = v[ j ] * _canvas.height;
_ctx.fillStyle = _colours[ j ];
_ctx.fillRect( _canvas.width - 1, th, 1, h );
th += h;
} );
}
_init();
return {
draw: _draw
};
}
function PerfCounter ( id, group ) {
var _id = id,
_time,
_value = 0,
_total = 0,
_averageValue = 0,
_accumValue = 0,
_accumStart = performance.now(),
_accumSamples = 0,
_dom = document.createElement( 'div' ),
_spanId = document.createElement( 'span' ),
_spanValue = document.createElement( 'div' ),
_spanValueText = document.createTextNode( '' ),
_def = _settings ? _settings.values[ _id.toLowerCase() ] : null,
_graph = new Graph( _dom, _id, _def ),
_started = false;
_spanId.className = 'rs-counter-id';
_spanId.textContent = ( _def && _def.caption ) ? _def.caption : _id;
_spanValue.className = 'rs-counter-value';
_spanValue.appendChild( _spanValueText );
_dom.appendChild( _spanId );
_dom.appendChild( _spanValue );
if ( group ) group.div.appendChild( _dom );
else _div.appendChild( _dom );
_time = performance.now();
function _average ( v ) {
if ( _def && _def.average ) {
_accumValue += v;
_accumSamples++;
var t = performance.now();
if ( t - _accumStart >= ( _def.avgMs || 1000 ) ) {
_averageValue = _accumValue / _accumSamples;
_accumValue = 0;
_accumStart = t;
_accumSamples = 0;
}
}
}
function _start () {
_time = performance.now();
if( _settings.userTimingAPI ) performance.mark( _id + '-start' );
_started = true;
}
function _end () {
_value = performance.now() - _time;
if( _settings.userTimingAPI ) {
performance.mark( _id + '-end' );
if( _started ) {
performance.measure( _id, _id + '-start', _id + '-end' );
}
}
_average( _value );
}
function _tick () {
_end();
_start();
}
function _draw () {
var v = ( _def && _def.average ) ? _averageValue : _value;
_spanValueText.nodeValue = Math.round( v * 100 ) / 100;
var a = ( _def && ( ( _def.below && _value < _def.below ) || ( _def.over && _value > _def.over ) ) );
_graph.draw( _value, a );
_dom.className = a ? 'rs-counter-base alarm' : 'rs-counter-base';
}
function _frame () {
var t = performance.now();
var e = t - _time;
_total++;
if ( e > 1000 ) {
if ( _def && _def.interpolate === false ) {
_value = _total;
} else {
_value = _total * 1000 / e;
}
_total = 0;
_time = t;
_average( _value );
}
}
function _set ( v ) {
_value = v;
_average( _value );
}
return {
set: _set,
start: _start,
tick: _tick,
end: _end,
frame: _frame,
value: function () {
return _value;
},
draw: _draw
};
}
function sample () {
var _value = 0;
function _set ( v ) {
_value = v;
}
return {
set: _set,
value: function () {
return _value;
}
};
}
function _perf ( idArg ) {
var id = idArg.toLowerCase();
if ( id === undefined ) id = 'default';
if ( _perfCounters[ id ] ) return _perfCounters[ id ];
var group = null;
if ( _settings && _settings.groups ) {
iterateKeys( _settings.groups, function ( j ) {
var g = _settings.groups[ parseInt( j, 10 ) ];
if ( !group && g.values.indexOf( id.toLowerCase() ) !== -1 ) {
group = g;
}
} );
}
var p = new PerfCounter( id, group );
_perfCounters[ id ] = p;
return p;
}
function _init () {
if ( _settings.plugins ) {
if ( !_settings.values ) _settings.values = {};
if ( !_settings.groups ) _settings.groups = [];
if ( !_settings.fractions ) _settings.fractions = [];
for ( var j = 0; j < _settings.plugins.length; j++ ) {
_settings.plugins[ j ].attach( _perf );
iterateKeys( _settings.plugins[ j ].values, function ( k ) {
_settings.values[ k ] = _settings.plugins[ j ].values[ k ];
} );
_settings.groups = _settings.groups.concat( _settings.plugins[ j ].groups );
_settings.fractions = _settings.fractions.concat( _settings.plugins[ j ].fractions );
}
} else {
_settings.plugins = {};
}
_base = document.createElement( 'div' );
_base.className = 'rs-base';
_div = document.createElement( 'div' );
_div.className = 'rs-container';
_div.style.height = 'auto';
_base.appendChild( _div );
document.body.appendChild( _base );
if ( !_settings ) return;
if ( _settings.groups ) {
iterateKeys( _settings.groups, function ( j ) {
var g = _settings.groups[ parseInt( j, 10 ) ];
var div = document.createElement( 'div' );
div.className = 'rs-group';
g.div = div;
var h1 = document.createElement( 'h1' );
h1.textContent = g.caption;
h1.addEventListener( 'click', function ( e ) {
this.classList.toggle( 'hidden' );
e.preventDefault();
}.bind( div ) );
_div.appendChild( h1 );
_div.appendChild( div );
} );
}
if ( _settings.fractions ) {
iterateKeys( _settings.fractions, function ( j ) {
var f = _settings.fractions[ parseInt( j, 10 ) ];
var div = document.createElement( 'div' );
div.className = 'rs-fraction';
var legend = document.createElement( 'div' );
legend.className = 'rs-legend';
var h = 0;
iterateKeys( _settings.fractions[ j ].steps, function ( k ) {
var p = document.createElement( 'p' );
p.textContent = _settings.fractions[ j ].steps[ k ];
p.style.color = _colours[ h ];
legend.appendChild( p );
h++;
} );
div.appendChild( legend );
div.style.height = h * _elHeight + 'px';
f.div = div;
var graph = new StackGraph( div, h );
f.graph = graph;
_div.appendChild( div );
} );
}
}
function _update () {
iterateKeys( _settings.plugins, function ( j ) {
_settings.plugins[ j ].update();
} );
iterateKeys( _perfCounters, function ( j ) {
_perfCounters[ j ].draw();
} );
if ( _settings && _settings.fractions ) {
iterateKeys( _settings.fractions, function ( j ) {
var f = _settings.fractions[ parseInt( j, 10 ) ];
var v = [];
var base = _perfCounters[ f.base.toLowerCase() ];
if ( base ) {
base = base.value();
iterateKeys( _settings.fractions[ j ].steps, function ( k ) {
var s = _settings.fractions[ j ].steps[ parseInt( k, 10 ) ].toLowerCase();
var val = _perfCounters[ s ];
if ( val ) {
v.push( val.value() / base );
}
} );
}
f.graph.draw( v );
} );
}
/*if( _height != _div.clientHeight ) {
_height = _div.clientHeight;
_base.style.height = _height + 2 * _elHeight + 'px';
console.log( _base.clientHeight );
}*/
}
_init();
return function ( id ) {
if ( id ) return _perf( id );
return {
element: _base,
update: _update
};
};
}
if (typeof module === 'object') {
module.exports = window.rStats;
}