mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Improved PrePro to be able to dynamically load Node.js code too, and improve load.js to handle both environments.
Also moved PaperScript .pjs extension code to PaperScript, and DOM related Node.js code to dom/node.js
This commit is contained in:
parent
94ce1f1312
commit
4f5dac8567
10 changed files with 148 additions and 139 deletions
|
@ -6,7 +6,6 @@ var data = "data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEd
|
|||
paper.setup(new paper.Canvas(600, 600));
|
||||
|
||||
with (paper) {
|
||||
console.log(Raster);
|
||||
var raster = new paper.Raster(data);
|
||||
raster.position = view.center;
|
||||
paper.view.exportFrames({
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"Jürg Lehni <juerg@lehni.org> (http://lehni.org)",
|
||||
"Jonathan Puckey <jonathan@studiomoniker.com> (http://studiomoniker.com)"
|
||||
],
|
||||
"main": "./src/node/index.js",
|
||||
"main": "./src/load.js",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
},
|
||||
|
@ -29,7 +29,7 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"uglify-js": "~2.3.6",
|
||||
"prepro": "~0.6.0",
|
||||
"prepro": "~0.7.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-uglify": "~0.2.2"
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// main paper scope, and is added to the PaperScope class. This allows for
|
||||
// better minification and the future use of strict mode once it makes sense
|
||||
// in terms of performance.
|
||||
paper.PaperScope.prototype.PaperScript = new function() {
|
||||
var PaperScript = paper.PaperScope.prototype.PaperScript = new function() {
|
||||
/*#*/ if (options.parser == 'acorn') {
|
||||
/*#*/ include('../../components/acorn/acorn.min.js');
|
||||
/*#*/ } else if (options.parser == 'esprima') {
|
||||
|
@ -332,3 +332,24 @@ paper.PaperScope.prototype.PaperScript = new function() {
|
|||
|
||||
/*#*/ } // !options.browser
|
||||
};
|
||||
|
||||
/*#*/ if (options.node) {
|
||||
|
||||
// Register the .pjs extension and have it automatically compile as PaperScript
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
require.extensions['.pjs'] = function(module, uri) {
|
||||
var source = PaperScript.compile(fs.readFileSync(uri, 'utf8')),
|
||||
scope = new PaperScope();
|
||||
scope.__filename = uri;
|
||||
scope.__dirname = path.dirname(uri);
|
||||
// Expose core methods and values
|
||||
scope.require = require;
|
||||
scope.console = console;
|
||||
PaperScript.evaluate(source, scope);
|
||||
module.exports = scope;
|
||||
};
|
||||
|
||||
/*#*/ } // options.node
|
||||
|
|
59
src/dom/node.js
Normal file
59
src/dom/node.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
// Node.js emulation layer of browser based environment, based on node-canvas
|
||||
// and jsdom.
|
||||
|
||||
// console.log(__dirname);
|
||||
|
||||
var jsdom = require('jsdom'),
|
||||
domToHtml = require('jsdom/lib/jsdom/browser/domtohtml').domToHtml,
|
||||
// Node Canvas library: https://github.com/learnboost/node-canvas
|
||||
Canvas = require('canvas');
|
||||
|
||||
// Expose global browser variables and create a document and a window using
|
||||
// jsdom, e.g. for import/exportSVG()
|
||||
var document = jsdom.jsdom('<html><body></body></html>'),
|
||||
window = document.createWindow(),
|
||||
navigator = window.navigator,
|
||||
HTMLCanvasElement = Canvas,
|
||||
Image = Canvas.Image;
|
||||
|
||||
// Define XMLSerializer and DOMParser shims, to emulate browser behavior.
|
||||
// TODO: Put this into a simple node module, with dependency on jsdom?
|
||||
function XMLSerializer() {
|
||||
}
|
||||
|
||||
XMLSerializer.prototype.serializeToString = function(node) {
|
||||
var text = domToHtml(node);
|
||||
// Fix a jsdom issue where all SVG tagNames are lowercased:
|
||||
// https://github.com/tmpvar/jsdom/issues/620
|
||||
var tagNames = ['linearGradient', 'radialGradient', 'clipPath'];
|
||||
for (var i = 0, l = tagNames.length; i < l; i++) {
|
||||
var tagName = tagNames[i];
|
||||
text = text.replace(
|
||||
new RegExp('(<|</)' + tagName.toLowerCase() + '\\b', 'g'),
|
||||
function(all, start) {
|
||||
return start + tagName;
|
||||
});
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
function DOMParser() {
|
||||
}
|
||||
|
||||
DOMParser.prototype.parseFromString = function(string, contenType) {
|
||||
var div = doc.createElement('div');
|
||||
div.innerHTML = string;
|
||||
return div.firstChild;
|
||||
};
|
|
@ -13,6 +13,8 @@
|
|||
// First add Base and a couple of other objects that are not automatically
|
||||
// exported to exports (Numerical, Key, etc), then inject all exports into
|
||||
// PaperScope, and create the initial paper object, all in one statement:
|
||||
/*#*/ if (options.browser) {
|
||||
|
||||
paper = new (PaperScope.inject(Base.merge(Base.exports, {
|
||||
// Mark fields as enumeralbe so PaperScope.inject can pick them up
|
||||
enumerable: true,
|
||||
|
@ -26,3 +28,19 @@ paper = new (PaperScope.inject(Base.merge(Base.exports, {
|
|||
// Support AMD (e.g. require.js)
|
||||
if (typeof define === 'function' && define.amd)
|
||||
define(paper);
|
||||
|
||||
/*#*/ } else if (options.node) {
|
||||
|
||||
paper = new (PaperScope.inject(Base.merge(Base.exports, {
|
||||
// Mark fields as enumeralbe so PaperScope.inject can pick them up
|
||||
enumerable: true,
|
||||
Base: Base,
|
||||
Numerical: Numerical,
|
||||
DomElement: DomElement,
|
||||
// Export dom/node.js stuff too
|
||||
XMLSerializer: XMLSerializer,
|
||||
DOMParser: DOMParser,
|
||||
Canvas: Canvas
|
||||
})))();
|
||||
|
||||
/*#*/ } // options.node
|
||||
|
|
34
src/load.js
34
src/load.js
|
@ -14,20 +14,40 @@
|
|||
// the browser, avoiding the step of having to manually preprocess it after each
|
||||
// change. This is very useful during development of the library itself.
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
// Browser based loading through PrePro:
|
||||
if (!window.include) {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var src = scripts[scripts.length - 1].getAttribute('src');
|
||||
// Assume that we're loading load.js from a root folder, either through
|
||||
// dist/paper.js symbolic link, or directly through src/load.js, and match
|
||||
// Assume that we're loading browser.js from a root folder, either
|
||||
// through dist/paper.js, or directly through src/load.js, and match
|
||||
// root as all the parts of the path that lead to that folder.
|
||||
var root = src.match(/^(.*\/)\w*\//)[1];
|
||||
// First load the PrePro's load.js file, which provides the include()
|
||||
// First load the PrePro's browser.js file, which provides the include()
|
||||
// function for the browser.
|
||||
document.write('<script type="text/javascript" src="' + root + 'node_modules/prepro/lib/load.js"></script>');
|
||||
// Now that we have include(), load this file again, which will execute the
|
||||
// lower part of the code the 2nd time around.
|
||||
document.write('<script type="text/javascript" src="' + root + 'src/load.js"></script>');
|
||||
document.write('<script type="text/javascript" src="' + root
|
||||
+ 'node_modules/prepro/lib/browser.js"></script>');
|
||||
// Now that we have include(), load this file again, which will execute
|
||||
// the lower part of the code the 2nd time around.
|
||||
document.write('<script type="text/javascript" src="' + root
|
||||
+ 'src/load.js"></script>');
|
||||
} else {
|
||||
include('options.js');
|
||||
include('paper.js');
|
||||
}
|
||||
} else {
|
||||
// Node based loading through PrePro:
|
||||
var prepro = require('prepro/lib/node.js');
|
||||
// Include deafult browser options.
|
||||
prepro.include('options.js');
|
||||
// Override node specific options.
|
||||
prepro.setOptions({
|
||||
browser: false,
|
||||
node: true,
|
||||
stats: false
|
||||
});
|
||||
// Load Paper.js library files.
|
||||
prepro.include('paper.js');
|
||||
// Export the paper scope.
|
||||
module.exports = prepro.context.paper;
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
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'),
|
||||
domToHtml = require('jsdom/lib/jsdom/browser/domtohtml').domToHtml;
|
||||
|
||||
// Load the options from load.js, but evaluate into local scope:
|
||||
eval(fs.readFileSync(path.resolve(__dirname, '../options.js'), 'utf8'));
|
||||
// Change node.js specific settings. Use 'dev' version for on-the fly
|
||||
// compilation of separate files, and set to correct value after.
|
||||
options.version = 'dev';
|
||||
options.browser = false;
|
||||
options.node = true;
|
||||
options.stats = false;
|
||||
|
||||
// Create a document and a window using jsdom, e.g. for exportSVG()
|
||||
var doc = jsdom.jsdom('<html><body></body></html>'),
|
||||
win = doc.createWindow();
|
||||
|
||||
// Define XMLSerializer and DOMParser shims, to emulate browser behavior.
|
||||
// TODO: Put this into a simple node module, with dependency on jsdom?
|
||||
function XMLSerializer() {
|
||||
}
|
||||
|
||||
XMLSerializer.prototype.serializeToString = function(node) {
|
||||
var text = domToHtml(node);
|
||||
// Fix a jsdom issue where all SVG tagNames are lowercased:
|
||||
// https://github.com/tmpvar/jsdom/issues/620
|
||||
var tagNames = ['linearGradient', 'radialGradient', 'clipPath'];
|
||||
for (var i = 0, l = tagNames.length; i < l; i++) {
|
||||
var tagName = tagNames[i];
|
||||
text = text.replace(
|
||||
new RegExp('(<|</)' + tagName.toLowerCase() + '\\b', 'g'),
|
||||
function(all, start) {
|
||||
return start + tagName;
|
||||
});
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
function DOMParser() {
|
||||
}
|
||||
|
||||
DOMParser.prototype.parseFromString = function(string, contenType) {
|
||||
var div = doc.createElement('div');
|
||||
div.innerHTML = string;
|
||||
return div.firstChild;
|
||||
};
|
||||
|
||||
// Create the context within which we will run the source files:
|
||||
var dirname = path.resolve(__dirname, '..');
|
||||
var context = vm.createContext({
|
||||
// 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:
|
||||
prevDirname = dirname;
|
||||
dirname = path.resolve(dirname, path.dirname(uri));
|
||||
vm.runInContext(source, context, uri);
|
||||
dirname = prevDirname;
|
||||
},
|
||||
// Expose core methods and values
|
||||
__dirname: dirname,
|
||||
require: require,
|
||||
options: options,
|
||||
// Expose node modules
|
||||
fs: fs,
|
||||
Canvas: Canvas,
|
||||
// Expose global browser variables:
|
||||
HTMLCanvasElement: Canvas,
|
||||
XMLSerializer: XMLSerializer,
|
||||
DOMParser: DOMParser,
|
||||
Image: Canvas.Image,
|
||||
window: win,
|
||||
document: doc,
|
||||
navigator: win.navigator,
|
||||
console: console
|
||||
});
|
||||
|
||||
// Load Paper.js library files:
|
||||
context.include('paper.js');
|
||||
|
||||
context.PaperScope.inject({
|
||||
// Expose the Canvas, XMLSerializer & DOMParser to PaperScope:
|
||||
Canvas: Canvas,
|
||||
XMLSerializer: XMLSerializer,
|
||||
DOMParser: DOMParser,
|
||||
// Also set the correct version from package.json
|
||||
version: require('../../package.json').version
|
||||
});
|
||||
|
||||
require.extensions['.pjs'] = function(module, uri) {
|
||||
var source = context.PaperScript.compile(fs.readFileSync(uri, 'utf8'));
|
||||
// Temporarily override __dirname and __filename
|
||||
var envVars = 'var __dirname = \'' + path.dirname(uri) + '\';'
|
||||
+ 'var __filename = \'' + uri + '\';';
|
||||
vm.runInContext(envVars, context);
|
||||
var scope = new context.PaperScope();
|
||||
context.PaperScript.evaluate(source, scope);
|
||||
module.exports = scope;
|
||||
};
|
||||
|
||||
module.exports = context.paper;
|
|
@ -10,8 +10,9 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
// Define default options for compile-time preprocessing. These are also used
|
||||
// for building, but some values are overridden (e.g. version, stats).
|
||||
// Define default options for browser based compile-time preprocessing.
|
||||
// These are also used for building, but some values are overridden
|
||||
// (e.g. version, stats).
|
||||
|
||||
var options = {
|
||||
parser: 'acorn',
|
||||
|
|
|
@ -91,8 +91,14 @@ var paper = new function() {
|
|||
/*#*/ include('style/GradientStop.js');
|
||||
/*#*/ include('style/Style.js');
|
||||
|
||||
/*#*/ if (options.node) {
|
||||
/*#*/ include('dom/node.js');
|
||||
/*#*/ } // options.node
|
||||
/*#*/ include('dom/DomElement.js');
|
||||
/*#*/ if (options.browser) {
|
||||
// DomEvent doesn't make sense outside of the browser (yet)
|
||||
/*#*/ include('dom/DomEvent.js');
|
||||
/*#*/ } // options.browser
|
||||
|
||||
/*#*/ include('ui/View.js');
|
||||
/*#*/ include('ui/CanvasView.js');
|
||||
|
|
|
@ -183,6 +183,9 @@ CanvasView.inject(new function() {
|
|||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
return {
|
||||
// DOCS: CanvasView#exportFrames(param);
|
||||
exportFrames: function(param) {
|
||||
|
|
Loading…
Reference in a new issue