From 8dbe1f4927e85219f39966a39573c94b380b63b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Wed, 8 May 2013 18:17:23 -0700 Subject: [PATCH] Fix issues with running paper.js in node. We need to export the Object and Array definition into new context, to make Base.isPlainObject() work. See http://nodejs.org/api/vm.html#vm_globals --- src/node/index.js | 49 +++++++++++++++++++++++++------------------- src/ui/CanvasView.js | 16 +++++++-------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/node/index.js b/src/node/index.js index 65bfbc42..520442f3 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -13,10 +13,17 @@ var fs = require('fs'), vm = require('vm'), path = require('path'), + // Node Canvas library: https://github.com/learnboost/node-canvas Canvas = require('canvas'), - jsdom = require('jsdom'); + jsdom = require('jsdom'), + dirname = path.resolve(__dirname, '..'); -__dirname = path.resolve(__dirname, '..'); +var options = { + server: true, + svg: true, + parser: 'acorn', + version: 'dev' +}; // Create a window and document using jsdom, e.g. for exportSVG() var win = jsdom.createWindow(), @@ -24,14 +31,12 @@ var win = jsdom.createWindow(), // Create the context within which we will run the source files: var context = vm.createContext({ - options: { - server: true, - svg: true, - parser: 'acorn', - version: 'dev' - }, + options: options, fs: fs, - // Node Canvas library: https://github.com/learnboost/node-canvas + // We need to export the local Object definition, so Base.isPlainObject() + // works. See http://nodejs.org/api/vm.html#vm_globals + Object: Object, + Array: Array, Canvas: Canvas, HTMLCanvasElement: Canvas, Image: Canvas.Image, @@ -41,17 +46,16 @@ var context = vm.createContext({ navigator: win.navigator, console: console, require: require, - __dirname: __dirname, - __filename: __filename, + __dirname: dirname, // Used to load and run source files within the same context: include: function(uri) { - var source = fs.readFileSync(path.resolve(__dirname, uri), 'utf8'); - // For relative includes, we save the current directory and then - // add the uri directory to __dirname: - var oldDirname = __dirname; - __dirname = path.resolve(__dirname, path.dirname(uri)); + var source = fs.readFileSync(path.resolve(dirname, uri), 'utf8'), + // For relative includes, we save the current directory and then + // add the uri directory to dirname: + prevDirname = dirname; + dirname = path.resolve(dirname, path.dirname(uri)); vm.runInContext(source, context, uri); - __dirname = oldDirname; + dirname = prevDirname; } }); @@ -63,15 +67,18 @@ context.Base.each(context, function(val, key) { if (val && val.prototype instanceof context.Base) context.PaperScope.prototype[key] = val; }); -context.PaperScope.prototype['Canvas'] = context.Canvas; +context.PaperScope.prototype.Canvas = Canvas; require.extensions['.pjs'] = function(module, uri) { var source = context.PaperScript.compile(fs.readFileSync(uri, 'utf8')); - var envVars = 'var __dirname = \'' + path.dirname(uri) + '\';' + - 'var __filename = \'' + uri + '\';'; - vm.runInContext(envVars, context); + var prevDirname = context.__dirname, + prevFilename = context.__filename; + context.__dirname = path.dirname(uri); + context.__filename = uri; var scope = new context.PaperScope(); context.PaperScript.evaluate(source, scope); + context.__dirname = prevDirname; + context.__filename = prevFilename; module.exports = scope; }; diff --git a/src/ui/CanvasView.js b/src/ui/CanvasView.js index 37b1649d..077f2b1e 100644 --- a/src/ui/CanvasView.js +++ b/src/ui/CanvasView.js @@ -172,7 +172,6 @@ var CanvasView = View.extend(/** @lends CanvasView# */{ /*#*/ if (options.server) { // Node.js server based image exporting code. CanvasView.inject(new function() { - var path = require('path'); // Utility function that converts a number to a string with // x amount of padded 0 digits: function toPaddedString(number, length) { @@ -196,7 +195,8 @@ CanvasView.inject(new function() { var view = this, count = 0, frameDuration = 1 / param.fps, - lastTime = startTime = Date.now(); + startTime = Date.now(), + lastTime = startTime; // Start exporting frames by exporting the first frame: exportFrame(param); @@ -204,8 +204,8 @@ CanvasView.inject(new function() { function exportFrame(param) { count++; var filename = param.prefix + toPaddedString(count, 6) + '.png', - uri = param.directory + '/' + filename; - var out = view.exportImage(uri, function() { + path = param.directory + '/' + filename; + var out = view.exportImage(path, function() { // When the file has been closed, export the next fame: var then = Date.now(); if (param.onProgress) { @@ -237,11 +237,11 @@ CanvasView.inject(new function() { } } }, - // DOCS: View#exportImage(uri, callback); - exportImage: function(uri, callback) { + + // DOCS: View#exportImage(path, callback); + exportImage: function(path, callback) { this.draw(); - // TODO: is it necessary to resolve the path? - var out = fs.createWriteStream(path.resolve(__dirname, uri)), + var out = fs.createWriteStream(path), stream = this._element.createPNGStream(); // Pipe the png stream to the write stream: stream.pipe(out);