stats.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // stats.js -
  2. // @author mrdoob http://github.com/mrdoob/stats.js
  3. // The MIT License
  4. //
  5. // Copyright (c) 2009-2016 stats.js author mrdoob / http://mrdoob.com/
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. */
  25. var Stats = function () {
  26. this.fps = 0;
  27. var mode = 0;
  28. var container = document.createElement( 'div' );
  29. container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';
  30. container.addEventListener( 'click', function ( event ) {
  31. event.preventDefault();
  32. showPanel( ++ mode % container.children.length );
  33. }, false );
  34. //
  35. function addPanel( panel ) {
  36. container.appendChild( panel.dom );
  37. return panel;
  38. }
  39. function showPanel( id ) {
  40. for ( var i = 0; i < container.children.length; i ++ ) {
  41. container.children[ i ].style.display = i === id ? 'block' : 'none';
  42. }
  43. mode = id;
  44. }
  45. //
  46. var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;
  47. var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) );
  48. var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) );
  49. if ( self.performance && self.performance.memory ) {
  50. var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) );
  51. }
  52. showPanel( 0 );
  53. return {
  54. REVISION: 16,
  55. dom: container,
  56. addPanel: addPanel,
  57. showPanel: showPanel,
  58. begin: function () {
  59. beginTime = ( performance || Date ).now();
  60. },
  61. end: function () {
  62. frames ++;
  63. var time = ( performance || Date ).now();
  64. msPanel.update( time - beginTime, 200 );
  65. if ( time > prevTime + 3000 ) {
  66. this.fps = ( frames * 1000 ) / ( time - prevTime );
  67. fpsPanel.update( this.fps, 100 );
  68. prevTime = time;
  69. frames = 0;
  70. if ( memPanel ) {
  71. var memory = performance.memory;
  72. memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );
  73. }
  74. }
  75. return time;
  76. },
  77. update: function () {
  78. beginTime = this.end();
  79. },
  80. // Backwards Compatibility
  81. domElement: container,
  82. setMode: showPanel
  83. };
  84. };
  85. Stats.Panel = function ( name, fg, bg ) {
  86. var min = Infinity, max = 0, round = Math.round;
  87. var PR = round( window.devicePixelRatio || 1 );
  88. var WIDTH = 80 * PR, HEIGHT = 48 * PR,
  89. TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
  90. GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
  91. GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
  92. var canvas = document.createElement( 'canvas' );
  93. canvas.width = WIDTH;
  94. canvas.height = HEIGHT;
  95. canvas.style.cssText = 'width:80px;height:48px';
  96. var context = canvas.getContext( '2d' );
  97. context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';
  98. context.textBaseline = 'top';
  99. context.fillStyle = bg;
  100. context.fillRect( 0, 0, WIDTH, HEIGHT );
  101. context.fillStyle = fg;
  102. context.fillText( name, TEXT_X, TEXT_Y );
  103. context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
  104. context.fillStyle = bg;
  105. context.globalAlpha = 0.9;
  106. context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
  107. return {
  108. dom: canvas,
  109. update: function ( value, maxValue ) {
  110. min = Math.min( min, value );
  111. max = Math.max( max, value );
  112. context.fillStyle = bg;
  113. context.globalAlpha = 1;
  114. context.fillRect( 0, 0, WIDTH, GRAPH_Y );
  115. context.fillStyle = fg;
  116. context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );
  117. context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );
  118. context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );
  119. context.fillStyle = bg;
  120. context.globalAlpha = 0.9;
  121. context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );
  122. }
  123. };
  124. };
  125. if ( typeof module === 'object' ) {
  126. module.exports = Stats;
  127. }