timeweb is a JavaScript library that overwrites native time handling in a web page, creating a virtual timeline independent of real time.
# Scope
timeweb overwrites these time-related features in web pages:
performance.now()
,Date.now()
,new Date()
, andDate()
requestAnimationFrame()
andcancelAnimationFrame()
setTimeout()
,setInterval()
,clearTimeout()
, andclearInterval()
- CSS Transitions and Animations
- SVG Animations
- Videos
- element
.animate()
new CustomEvent().timeStamp
# timeweb Limitations
These time-related features are known not to work:
- iframes with time-related content
- event.timeStamp
- Audio analyser nodes
Additionally timeweb is limited by what can be overwritten in browser by JavaScript and not everything may work as intended. Please file an issue if you think something should work.
# Script Use
- Copy
dist/timeweb.js
to the desired directory. - Include it before any time-handling JavaScript in the HTML file:
<script src="path/to/timeweb.js"></script>
- Use
timeweb.goTo
to go to a virtual time, in milliseconds. For instance,timeweb.goTo(5000);
goes to 5 seconds on the virtual time line. It can only go forward. Note that currentlyrequestAnimationFrame
is called once pertimeweb.goTo
regardless of the previous virtual time.
# How it works
For JavaScript functions, timeweb overwrites a page's native time-handling functions and objects (new Date()
, Date.now
, performance.now
, requestAnimationFrame
, setTimeout
, setInterval
, cancelAnimationFrame
, clearTimeout
, and clearInterval
) to custom ones that use a virtual timeline, which can be stepped through programmatically.
For videos/SVGs, timeweb detects when video
and svg
elements are created or added to the page by using a mutation observer and overwriting document.createElement
. It pauses those elements and seeks when needed.
For animations available through the Web Animations API(CSS Transitions, CSS Animations, and element.animate()
), timeweb detects new animations through transitionstart
, animationrun
listeners, document.getAnimations
, and overwriting Element.prototype.animate
. It pauses the animations and seeks when needed.
This work was inspired by a talk by Noah Veltman, who described altering a document's Date.now
and performance.now
functions to refer to a virtual time and using puppeteer
to change that virtual time and take snapshots.