node package manager


Animitter is an animation loop + EventEmitter for browser, node, browserify or amd.


by Kyle Phillips

Animitter is a combination of an EventEmitter and a feature-filled animation loop. It uses requestAnimationFrame with an automatic fallback to setTimeout and offers several additional features, such as framerate throttling, easy starting and stopping of the loop, providing deltaTime in milliseconds between frames, as well as total elapsedTime and frameCount. Listen to the built-in update, start, stop, complete and reset events, or emit your own.

npm install animitter --save

copy ./animitter.js or ./animitter.min.js into your project

<script src="js/animitter.js"></script>

or with require.js/amd:

require(['animitter'], function( animitter ){});
var loop = animitter(function(deltaTime, elapsedTime, frameCount){
    //do something 
var loop = animitter(function(deltaTime, elapsedTime, frameCount){
    //do something 
loop.on('start', function(deltaTime, elapsedTime, frameCount){
    //loop started 
loop.on('update', function(deltaTime, elapsedTime, frameCount){
    if( frameCount === 100 ){
        //`this` is scoped to the Animitter instance 
loop.on('stop', function(deltaTime, elapsedTime, frameCount){
    //this will get triggered on a `complete` also 
loop.on('complete', function(deltaTime, elapsedTime, frameCount){
    //done, can't be started again unless reset 
loop.on('reset', function(deltaTime, elapsedTime, frameCount){

Animitter uses the same EventEmitter as Node.js. This allows you to emit events, add listeners with on,once,addListener or remove listeners with removeListener or removeAllListeners.

The following example periodically emits a custom event. A listener is added for the event which removes itself after a few uses:

var timesDovesHaveFlown = 0,
    shouldMakeDovesFly = function(){ return Math.random() > 0.9; };
var loop = animitter(function(deltaTime, elapsedTime, frameCount){
    //play an animation 
    if( shouldMakeDovesFly() ){
        //after the event-type, pass any parameters you want the listener to receive 
        this.emit('doves-fly', doves);
loop.on('doves-fly', function(doves){
    //make doves fly here 
    if( timesDovesHaveFlown > 4 ){
        this.removeListener('doves-fly', makeDovesFly);

Animitter inherits from EventEmitter which provides methods such as emit, on, removeListener etc… below (in alphabetical order) are the methods that animitter provides directly:

  • options.fps : Number defaults to 60, set a framerate between >0 and <=60.
  • options.fixedDelta : Boolean defaults to false, if true, 'update' events will always report deltaTime and elapsedTime as consistent framerate intervals. Useful in situations such as when you may be recording output at a rate different than real-time.

stop the loop and mark it as completed and unable to start again.

stop the loop and remove all listeners.

return the framerate, 0-60.

return the time between the last two frames in milliseconds

return the time between the last frame and the first frame in milliseconds.

return the number of times the loop has repeated.

return true if the loop is currently active

return true if the loop has been marked as completed.

stops the loop and resets its times, frameCount and whether it was completed, leaves listeners intact.

throttle the loop to a preferred framerate between 0-60.

starts repeating the update loop.

stops repeating the update loop.

updates the loop once.

The animitter object comes with the property running this counter indicates the number of animitter instances that are currently animating. This can be helpful for debugging to ensure that you are properly stopping all of your animitter instances.

Setting this to true will force all animitter instances to behave as if options.fixedDelta was true. A helpful application-wide toggle if you begin to record the output not in real-time.

Set a custom requestAnimationFrame, cancelAnimationFrame and its running frames per second. You can use this to force using setTimeout or to use WebVR's requestAnimationFrame for faster updates. Below is an example of using animitter.setAnimationFrame with WebVR:

    if(displays.length > 0){
        var hmd = displays[0];
        animitter.setAnimationFrame(hmd.requestAnimationFrame, hmd.cancelAnimationFrame, 90);

Get an object with the current requestAnimationFrame, cancelAnimationFrame, and fps.


let = { requestAnimationFrame, cancelAnimationFrame, fps } = animitter.getAnimationFrame();

Animitter comes with TAP tests. These tests are compatible in node and in browser. To run the tests in node:

npm test

To run tests in browser: A very simple way of accomplishing this, is to use something like budo and watch your console for logs:

npm install budo -g
budo test.js

In v1.0.0 a few aspects of the API have changed. Most notably the parameter signature of all events is now:

function onEvent( deltaTime, elapsedTime, frameCount ){ }

Additionally, animitter().isAnimating() has been renamed to isRunning() and { async: true } option no longer is available. Instead users should call animitter().update() directly to update their loop asynchronously.

MIT License