Last active
January 5, 2021 15:39
-
-
Save haxiomic/8ce12078301a6e6e9cfa to your computer and use it in GitHub Desktop.
TimeLord.js: hack javascript's sense of time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.TimeLord = (function(){ | |
/* | |
# Time accounted for | |
Date.now() | |
window.performance.now() | |
window.setInterval(...) | |
window.setTimeout(...) | |
window.requestAnimationFrame(...) | |
# Not accounted for | |
(new Date()).getTime() | |
*/ | |
var fakeTime_ms = 0; | |
var activateStamp = 0; | |
var intervalIdCounter = 1; | |
var intervals = []; | |
function stepTime(dt_ms){ | |
fakeTime_ms += dt_ms; | |
var i = intervals.length; | |
while(--i >= 0){ | |
var iObj = intervals[i]; | |
var dt = fakeTime_ms - iObj.start_ms; | |
if(dt >= iObj.ms){ | |
//fire | |
iObj.fn.apply(window, iObj.fnArgs); | |
if(iObj.loop){ | |
iObj.start_ms += iObj.ms; | |
}else{ | |
//remove | |
intervals.splice(i, 1); | |
} | |
} | |
} | |
} | |
function setTime(ms){ | |
if(ms < fakeTime_ms){ | |
console.warn('TimeLord: without a tardis or flux capacitor you\'re probably going to have errors if you try to go back in time'); | |
} | |
var dt_ms = ms - fakeTime_ms; | |
stepFakeTime(dt_ms);//call stepTime so our intervals get fired | |
} | |
function getTime(){ | |
return fakeTime_ms; | |
} | |
function addInterval(fn, ms, loop, fnArgs){ | |
var id = intervalIdCounter++; | |
intervals.push({ | |
id: id, | |
fn: fn, | |
ms: ms, | |
loop: loop, | |
fnArgs: fnArgs, | |
start_ms: fakeTime_ms, | |
}); | |
return id; | |
} | |
function removeInterval(id){ | |
var i = intervals.length; | |
while(--i >= 0){ | |
if(intervals[i].id === id){ | |
intervals.splice(i, 1); | |
break; | |
} | |
} | |
} | |
function activate(){ | |
//override javascript time functions | |
activateStamp = Date.now(); | |
//absolute time | |
Date._now = Date.now; | |
Date.now = function(){ | |
return activateStamp + fakeTime_ms; | |
} | |
window.performance._now = window.performance.now; | |
window.performance.now = function(){ | |
return fakeTime_ms; | |
} | |
//relative time | |
window._setTimeout = window.setTimeout; | |
window.setTimeout = function(fn, ms){ | |
var fnArgs = Array.prototype.slice.call(arguments, [2]); | |
return addInterval(fn, ms, false, fnArgs); | |
} | |
window._setInterval = window.setInterval; | |
window.setInterval = function(fn, ms){ | |
var fnArgs = Array.prototype.slice.call(arguments, [2]); | |
return addInterval(fn, ms, true, fnArgs); | |
} | |
window._clearInterval = window.clearInterval; | |
window.clearInterval = function(id){ | |
removeInterval(id); | |
} | |
window._clearTimeout = window.clearTimeout; | |
window.clearTimeout = function(id){ | |
removeInterval(id); | |
} | |
window._requestAnimationFrame = window.requestAnimationFrame; | |
window.requestAnimationFrame = function(cb){ | |
var newCb = function(realTime_ms){ | |
cb(fakeTime_ms); | |
} | |
return window._requestAnimationFrame(newCb); | |
} | |
} | |
return { | |
activate: activate, | |
stepTime: stepTime, | |
setTime: setTime, | |
getTime: getTime | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Original functions accessed by prefixing _, eg: Date._now()
Example usage: run time at 1/2 speed