Wondering what’s next for npm?Check out our public roadmap! »


    0.1.22 • Public • Published

    Scheduling regular updates in the interest of creating smooth running browser animations in JS might conceivably look a bit like,

    // Start
    function loop(now) {
      console.log(`update called ${now}ms into current document's lifetime`)
      // Repeat endlessly?

    Ending that loop on demand such as when debouncing mouse events would involve keeping track of each requestAnimationFrame or rAF index to then be calling cancelAnimationFrame with,

    // Start
    let frame = window.requestAnimationFrame(loop)
    function loop() {
      // Update
      frame = window.requestAnimationFrame(loop)
    function stop() {
      if (frame) {
        // Unassign, make falsy again
        frame = window.cancelAnimationFrame(frame)
      console.assert(frame === undefined)
    document.addEventListener('click', stop, { once: true })

    This module is essentially a closure around that otherwise free roaming frame reference. It includes no polyfill and minifies to less than half a kilobyte,

    # Includes ES and CJS versions 
    npm i @thewhodidthis/animation

    The default and only export is an anonymous function requiring a callback argument to be invoked before the next repaint, same as using rAF directly. In line with the revealing module pattern expect an anonymous object with start() and stop() methods attached and aliased play / pause respectively,

    import createLoop from '@thewhodidthis/animation'
    let frameMaybe
    const animationMethods = ['start', 'stop', 'play', 'pause']
    const animation = createLoop((now, frame) => {
      console.assert(frameMaybe === frame)
      frameMaybe = animation.stop()
      console.assert(frameMaybe === undefined)
    console.assert(Object.keys(animation).every(k => animationMethods.includes(k)))
    frameMaybe = animation.start()

    The callback is passed a DOMHighResTimeStamp and the frame reference. Just in case, checks are included to allow for running multiple loops in parallel.

    const startFrame = animation.start()
    const startAgainFrame = animation.start()
    console.assert(startFrame === startAgainFrame)


    npm i @thewhodidthis/animation

    DownloadsWeekly Downloads






    Unpacked Size

    41.1 kB

    Total Files


    Last publish


    • avatar