cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmlicon-personicon-teamoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
               <button onclick="testHiresTime()">Test</button> <button onclick="recalibrate()">Recalibrate</button>
<div id="output"></div>
            
          
!
            
              
// Replacement to performance.now() that is based on SharedArrayBuffer.  Used to get around the 5 microsecond resolution limit introduced as a response to the "Spy in the Sandbox" attack
// Returns the time in milliseconds since some arbtrary epoch, with around 4ns resolution.
// For more info: http://iss.oy.ne.ro/SpyInTheSandbox

// makeWorker is a little wrapper for generating web workers from strings
// Source: http://jsfiddle.net/bgrins/YUKSu/
function makeWorker(script) {
    var URL = window.URL || window.webkitURL;
    var Blob = window.Blob;
    var Worker = window.Worker;
    
    if (!URL || !Blob || !Worker || !script) {
        return null;
    }
    
    var blob = new Blob([script]);
    var worker = new Worker(URL.createObjectURL(blob));
    return worker;
}

var isCalibrated = false;
var counterThread = {};
var sharedCounter = new SharedUint32Array(1);
var CALIBRATION_PERIOD_IN_MS = 100;
var millisecondsPerCount = 0.0;
// 16/Jul/2015 - Mark's suggestion to speed it up by removing an indirect read
var counterThreadCode = "var sharedCounter = {}; self.addEventListener('message', function(e) {" +
        "var msg = e.data;" +
        "var currentValue = 0;" + 
        "switch(msg.opcode) {" +   
        "case 'init': sharedCounter = new SharedUint32Array(msg.sab); break;" +
    "case 'increment': do {" + 
    "currentValue = (currentValue + 1) | 0; " +
          "sharedCounter[0] = currentValue;} while (true);break;} " +
    "} ,false);"

// Bring up the thread
counterThread = makeWorker(counterThreadCode);
var msg = {opcode: "init", sab : sharedCounter.buffer};
counterThread.postMessage(msg, [msg.sab]);


function bufferBasedNow() {
  // If the code was never calibrated, start everything up.
  if (isCalibrated == false) {
    // Calibrate the timer
    var msg =  {opcode: "increment"};
    counterThread.postMessage(msg);

    var startTime = performance.now();
    var startCounter = sharedCounter[0];
    console.log("Calibrate start: " + sharedCounter[0]);

    do {} while (performance.now() - startTime < CALIBRATION_PERIOD_IN_MS);
    var endCounter = sharedCounter[0];
     console.log("Calibrate end: " + sharedCounter[0]);
  
    // Save the scaling factor
    millisecondsPerCount = CALIBRATION_PERIOD_IN_MS * 1.0 / (endCounter - startCounter);
    
    // Feed back the value of performance.now() into the counter so they stay in sync
    sharedCounter[0] = performance.now() / millisecondsPerCount;

    isCalibrated = true;
  }
  
  // Everything is calibrated, we can measure time.
  return sharedCounter[0] * millisecondsPerCount;
}


function testHiresTime() {
  // Measure 100ms using performance.now(), see how much the counter-based timer measured it as.
  var startTime = performance.now();
  var startTimeBB = bufferBasedNow();
  do {} while (performance.now() - startTime < 100);
  
  document.getElementById("output").innerHTML = "Performance.now() measured " + (performance.now() - startTime)+ " ms, bufferBasedNow() measured " + (bufferBasedNow() - startTimeBB + " ms.");
}

function recalibrate() {
  isCalibrated = false;
}

            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console