Advertisement
Guest User

Animation meter Canvas / JavaScript

a guest
Oct 3rd, 2013
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*!
  2.  *  Animation-meter version 1.0
  3.  *
  4.  *  Ken Fyrstenberg Nilsen (C) 2013 Abdias Software.
  5.  *  http://abdiassoftware.com/
  6.  *
  7.  *  MIT license.
  8. */
  9. /**
  10.  *  animMeter is a highly accurate meter to measure frames and FPS. It
  11.  *  is made to be used with canvas animations.
  12.  *
  13.  *  animMeter has a bar to show each individual frame rates, if they
  14.  *  operate within the "time budget" as well as an accurate FPS counter.
  15.  *
  16.  *  animMeter is very efficient an leaves a very tiny memory foot-print.
  17.  *
  18.  *  USAGE:
  19.  *
  20.  *      There are only two steps needed -
  21.  *
  22.  *      Initialization outside loop:
  23.  *
  24.  *          var meter = new animMeter(appendToIdOrElement)
  25.  *          var meter = new animMeter(appendToIdOrElement, systemFPS)
  26.  *
  27.  *      appendToIdOrElement   = id of an element or an element to append the meter to
  28.  *      systempFPS (optional) = if system Hz is not 60 Hz, pass in the frequency here
  29.  *
  30.  *      Inside loop right before calling requestAnimationFrame/setTimeout:
  31.  *
  32.  *          meter.update();          //if used from setTimeout (less accurate)
  33.  *          meter.update(rafResult); //rafResult from requestAnimationFrame
  34.  *
  35.  *  Note: if you choose to not use the event it will still be able to
  36.  *  measure, but less accurate.
  37.  *
  38.  *  Example:
  39.  *
  40.  *      var meter = new animMeter('myDiv'); //id or pass in an element directly
  41.  *
  42.  *      function loop(rafResult) {
  43.  *
  44.  *          // ...
  45.  *
  46.  *          meter.update(rafResult);
  47.  *          requestAnimationFrame(loop);
  48.  *      }
  49. */
  50. function animMeter(id, fps) {
  51.  
  52.     fps = fps ? fps : 60;
  53.  
  54.     var ctime, otime = null,    // current and old time
  55.         canvas, ctx,            // our canvas
  56.        
  57.         rw = 120,               // real width
  58.         nw = 18,                // fps area width
  59.         w = rw - nw,            // bar width
  60.         h = 10,                 // height
  61.         cx = 0,                 // bar x
  62.        
  63.         y = 2,                  // meter indicator height
  64.         mh = (h / 2 + y / 2)|0, // middle height
  65.         bh = h - y,             // bar width
  66.        
  67.         wx = w * 0.25,          // pre-calced for bar
  68.         interval = 1000 / fps,  // expected interval
  69.        
  70.         i = 0,                  // for rendering indicators
  71.         isNum = false,          // cache event number status
  72.         ut = 0, fpsa = 0,       // fps average counter
  73.         dx = 0, dy = 0,         // delta for Firefox
  74.  
  75.         cols = ['#0f0', '#ff0', '#fa0', '#f00'];
  76.  
  77.     /**
  78.      *  Call this from within the animation loop, right before calling
  79.      *  requestAnimationFrame (or setTimeout).
  80.     */
  81.     this.update = function(e) {
  82.  
  83.         var x, fps, diff;
  84.  
  85.         /// first time init
  86.         if (isNum || (arguments.length === 1 && typeof e !== 'undefined')) {
  87.  
  88.             if (otime === null) {
  89.                 otime = 0;
  90.                 isNum = true;
  91.                 return;
  92.             }
  93.             diff = e - otime;
  94.             otime = e;
  95.        
  96.         } else {
  97.  
  98.             if (otime === null) {
  99.                 otime = (new Date()).getTime();
  100.                 return;
  101.             }
  102.        
  103.             ctime = (new Date()).getTime();
  104.            
  105.             diff = ctime - otime;
  106.             otime = ctime;
  107.         }
  108.        
  109.         /// frame rate
  110.         fps = 1000 / diff;
  111.        
  112.         /// calc bar width - ideal result = 1
  113.         x = (wx * diff / interval)|0;
  114.         if (x > w) x = w;
  115.         if (x > cx) cx = x;
  116.  
  117.         /// render
  118.         ctx.beginPath();
  119.         ctx.moveTo(0, mh);
  120.         ctx.lineTo(cx, mh);
  121.         ctx.stroke();
  122.  
  123.         /// clear remaining
  124.         ctx.fillRect(cx, y, w - cx, bh);
  125.        
  126.         /// calc average FPS and update once every second
  127.         if (ut === 0) {
  128.  
  129.             ctx.beginPath();
  130.             ctx.fillRect(w, 0, nw, h);
  131.             ctx.fillStyle = '#ddf';
  132.             ctx.fillText(fpsa, w + nw + dx - 2, -1 + dy);
  133.             ctx.fillStyle = '#000';
  134.  
  135.             ut++;
  136.             fpsa = fps;
  137.            
  138.         } else {
  139.            
  140.             ut++;
  141.             fpsa += fps;
  142.            
  143.             if (ut > fps) {
  144.                 fpsa = (fpsa / ut + 0.5)|0;
  145.                 if (fpsa < 0) fpsa = 0;
  146.                 ut = 0;
  147.             }
  148.         }
  149.  
  150.         /// slow rest of bar
  151.         cx-=4;
  152.         if (cx < 1) cx = 1;
  153.     }
  154.  
  155.     /**
  156.      *  Setup canvas and render indicators to it
  157.     */
  158.     canvas = document.createElement('canvas');
  159.     canvas.width = rw;
  160.     canvas.height = h;
  161.     canvas.title = 'animMeter v.1.0 by Ken Fyrstenberg http://abdiassoftware.com/';
  162.     canvas.style.border = '2px solid #000';
  163.  
  164.     ctx = canvas.getContext('2d');
  165.  
  166.     /// for background
  167.     ctx.fillStyle = '#000';
  168.     ctx.fillRect(0, 0, rw, h);
  169.     ctx.lineWidth = 2;
  170.  
  171.     /// draw top indicators
  172.     for(; i < 4; i++) {
  173.         ctx.beginPath();
  174.         ctx.strokeStyle = cols[i];
  175.         ctx.moveTo((i * w * 0.25)|0, y-1);
  176.         ctx.lineTo((i * w * 0.25 + w * 0.25 - ((i<3)?1:0) )|0, y-1);
  177.         ctx.stroke();  
  178.     }
  179.  
  180.     /// webkit and firefox render text differently, compensate
  181.     if (typeof window.console.__mozillaConsole__ !== 'undefined') {
  182.         dx += 1;
  183.         dy += 2;
  184.     };
  185.    
  186.     /// for text
  187.     ctx.font = '9px Arial';
  188.     ctx.textAlign = 'end';
  189.     ctx.textBaseline = 'top';
  190.  
  191.     ctx.lineWidth = bh - 2;
  192.  
  193.     if (typeof id === 'string')
  194.         id = document.getElementById(id);
  195.    
  196.     id.appendChild(canvas);
  197.  
  198.     return this;
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement