ericdrowell/KineticJS — pull request #19 by bpartridge (2012-05-07 09:30:06+00:00)
Title: Node.js support: KineticJS working outside of the browser!

Enables KineticJS to work from Node.js using a [native-JS DOM](https://github.com/tmpvar/jsdom) and a [C++ canvas implementation](https://github.com/LearnBoost/node-canvas). Full browser compatibility is maintained with the same built javascript files, and minimal changes were made to the existing source code. What this makes possible:

* KineticJS on the server: render PNGs and PDFs server-side with the same code you use on the client, making web apps at least 20% cooler.
* Package management for complex client-side apps, using [node-browserify](https://github.com/substack/node-browserify).
* First to market: EaselJS is apparently architected in such a way to make Node integration much more difficult.

All unit tests pass except the following (yes, I read the readme :)):

var rect = new Kinetic.Rect({
x: 200,
y: 100,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});

...

test(rect.intersects({
x: 301,
y: 151
}) === false, 'intersects with point in shape');

This would appear to be a bug, but it's actually a different interpretation of the spec by the node-canvas authors at LearnBoost. Their C++ code for intersection is this:

Handle
Context2d::IsPointInPath(const Arguments &args) {
HandleScope scope;
if (args[0]->IsNumber() && args[1]->IsNumber()) {
Context2d *context = ObjectWrap::Unwrap(args.This());
cairo_t *ctx = context->context();
double x = args[0]->NumberValue()
, y = args[1]->NumberValue();
return scope.Close(Boolean::New(cairo_in_fill(ctx, x, y) || cairo_in_stroke(ctx, x, y)));
}
return False();
}

Note the `cairo_in_stroke` call... this means that assuming a one-pixel stroke, (301,151) would actually be inside the Rect. Will refrain from fixing until discussion occurs and we pin this down.