Find file
Fetching contributors…
Cannot retrieve contributors at this time
88 lines (55 sloc) 2.82 KB


NPM version

CAAT for Node.js

Note: For information about the CAAT library itself, please see the CAAT homepage.


This package imports the CAAT library for use in Node.js. It uses the jsdom and canvas packages to allow for offscreen rendering.


The canvas implementation requires Cairo. Please see the canvas Wiki for installation details for various platforms.


Install with npm:

$ npm install caat

or via git:

$ npm install git+


fs = require 'fs'
CAAT = require 'caat'

# Create a director and register it
director = new CAAT.Foundation.Director().initialize 200, 200
CAAT.RegisterDirector director

# Create a scene
scene = director.createScene()

# Create an actor
circle = new CAAT.Foundation.UI.ShapeActor()
  .setLocation(20, 20)
  .setSize(60, 60)

# Add the actor to the scene
scene.addChild circle

# Write rendered scene to a PNG file
out = fs.createWriteStream "#{__dirname}/canvas.png"
png = director.canvas.createPNGStream()
png.on 'data', (chunk) -> out.write chunk

# Render the frame at time 0


  • Rendering

The director normally renders via #renderFrame(), called by CAAT.loop(). However, the CAAT render loop is based on time elapsed between frame renders - which makes sense in a browser context. In node, you should call #render() directly, passing the global time in milliseconds to indicate which frame to render.

The only downside to this approach is that you lose render event notifications (since HTML events aren't supported by canvas). That's likely not a problem since you'll be manually rendering anyway.

  • Touch/Mouse Events

    All user-interaction events are disabled for obvious reasons. They could theoretically be enabled by altering CAAT.TOUCH_BEHAVIOR, but canvas doesn't support the required event handlers currently.

  • currentDirector

    CAAT uses the currentDirector property during the render loop to keep track of which director is rendering at the moment. It's also used for various things like image caching and actor positioning. Since the render loop is not used in node, you must manage currentDirector yourself. If you only have one director, calling CAAT.RegisterDirector() is sufficient. For multiple directors, you MUST set CAAT.currentDirector explicitly before calling #render() or manipulating actors within a scene (especially images).