tags:

views:

52

answers:

3

I'm writing a canvas-powered multiuser drawing application in Node.js, and want to maintain an internal canvas element with the current drawing. Is it possible to create and interact with a canvas element in Node.js?

My latest try was the jsdom module available here: http://github.com/tmpvar/jsdom

var jsdom = require('jsdom');
var window = jsdom.jsdom().createWindow();
var canvas = window.document.createElement('canvas');
// The following line works
canvas.setAttribute('width', 1000);
// The following line errors out on execution:
var context = canvas.getContext('2d');

Is there any other way to go about this?

+1  A: 

jsdom only implements the DOM interface, but the drawing context isn't part of that interface.

To get what you want one, would have to implement the 2D context:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvas-context-2d

I guess it could be done in JS using a gargantuan array... but it would be horrible slow. So either someone goes ahead and writes a C/C++ implementation for Node, or you're out of luck ATM.

I suppose that you need the internal state to initialize new clients, correct? In this case you could just push the drawing actions onto a stack and send that to the client, the client then pops the stack until he reached the current state of the drawing.

EDIT
OK apparently there's something over at the GitHubs:
http://github.com/joshthecoder/crayon

But it doesn't look like this is in any way production ready, the code is really sparse and there's only a test for surface creation. MAYBE the linker does some magic here and exposes the cairo stuff to node, but even then that would only expose the cairo functions them selfs and one would still have to implement the 2DContext spec on top of that.

Ivo Wetzel
You're exactly right :). Your suggestion is what I'm using now, but what I was going for was a super big buffer that's much more easily transferred as, say, a base64'ed png canvas export than a megalong array of lines. Unfortunately none of the Node.js graphics libraries seem up to snuff either, so it appears I'm stuck with the stack for now. Thanks!
Tom Frost
I edited my question, maybe you could use that as a base, in case you're really committed to your drawing app.
Ivo Wetzel
A: 

Large Javascript arrays aren't as slow as you might think (relative to Canvas operations). I've done a lot of performance testing with noVNC (HTML5 VNC client I made) and found that often doing manipulations on Javascript arrays is faster than Canvas operations. It's really going to depend on what type of modifications you are doing (transforms and complex lines will probably be faster as Canvas ops). So I would suggest actually performance testing both options before you decide.

In fact, I've done testing of using imageData arrays as a storage format instead of normal Javascript arrays, and imageData (even though they should be binary arrays) end up about 50% slower (in Chrome anyways) :-(

kanaka