Simplify the way PaperScope objects are created and linked to Canvas elements, in order to facilitate usage through plain JavaScript.

This commit is contained in:
Jürg Lehni 2011-07-27 22:39:58 +01:00
parent 3f76d1ffe6
commit 297aef643d
2 changed files with 62 additions and 61 deletions

View file

@ -19,22 +19,52 @@
* *
* @class The {@code PaperScope} class represents the scope associated with a * @class The {@code PaperScope} class represents the scope associated with a
* Paper context. When working with PaperScript, these scopes are automatically * Paper context. When working with PaperScript, these scopes are automatically
* created and their fields and methods become part of the global scope. When * created, and through clever scoping the fields and methods of the active
* working with normal JavaScript files, {@code PaperScope} objects need to be * scope seem to become part of the global scope. When working with normal
* manually created and handled. * JavaScript code, {@code PaperScope} objects need to be manually created and
* The global {@link paper} object is simply a reference to the * handled.
* currently active {@code PaperScope}. * Paper classes can only be accessed through {@code PaperScope} objects. Thus
* in PaperScript they are global, while in JavaScript, they are available on
* the global {@link paper} object, which is simply a reference to the currently
* active {@code PaperScope}.
*/ */
var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{ var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{
initialize: function(id) {
this.project = null; /**
this.projects = []; * Creates a PaperScope object and an empty {@link Project} for it. If a
this.view = null; * canvas is provided, it also creates a {@link View} for it.
* Both project and view are linked to this scope.
*
* @param {HTMLCanvasElement} canvas The canvas this scope should be
* associated with.
*/
initialize: function(canvas, script) {
// script is only used internally, when creating scopes for PaperScript.
// Whenever a PaperScope is created, it automatically becomes the active
// one.
paper = this;
this.views = []; this.views = [];
this.view = null;
this.projects = [];
// Since the global paper variable points to this PaperScope, the
// created project and view are automatically associated with it.
this.project = new Project();
this.tool = null; this.tool = null;
this.tools = []; this.tools = [];
this.id = id; var obj = script || canvas;
PaperScope._scopes[id] = this; this._id = obj && obj.getAttribute('id')
|| script && script.src
|| ('paperscope-' + (PaperScope._id++));
// Make sure the script tag also has this id now. If it already had an
// id, we're not changing it, since it's the first option we're
// trying to get an id from above.
if (script)
script.setAttribute('id', this._id);
PaperScope._scopes[this._id] = this;
if (canvas) {
// Create a view for the canvas.
this.view = new View(canvas);
}
}, },
/** /**
@ -86,23 +116,6 @@ var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{
return res; return res;
}, },
/**
* Sets up the scope for a standard project, by creating an empty
* {@link Project} object for us, along with a {@link View} for the passed
* canvas, both linked to this scope.
*/
setup: function(canvas) {
// We need to set the global paper reference to this scope,
// since that will be used in the Project constructor to set
// internal references.
paper = this;
new Project();
if (canvas) {
// Activate the newly created view straight away
new View(canvas).activate();
}
},
/** /**
* Injects the paper scope into any other given scope. Can be used for * Injects the paper scope into any other given scope. Can be used for
* examle to inject the currently active PaperScope into the window's global * examle to inject the currently active PaperScope into the window's global
@ -133,7 +146,7 @@ var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{
remove: function() { remove: function() {
this.clear(); this.clear();
delete PaperScope._scopes[this.id]; delete PaperScope._scopes[this._id];
}, },
_needsRedraw: function() { _needsRedraw: function() {
@ -147,6 +160,7 @@ var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{
statics: /** @lends PaperScope */{ statics: /** @lends PaperScope */{
_scopes: {}, _scopes: {},
_id: 0,
/** /**
* Retrieves a PaperScope object with the given id or associated with * Retrieves a PaperScope object with the given id or associated with

View file

@ -143,35 +143,17 @@ var PaperScript = this.PaperScript = new function() {
} }
/** /**
* Evaluates parsed PaperScript code in the passed scope. Also handles * Evaluates parsed PaperScript code in the passed {@link PaperScope}
* canvas setup, tool creation and handlers automatically. * object. It also handles canvas setup, tool creation and handlers
* automatically for us.
* *
* @name PaperScript.evaluate * @name PaperScript.evaluate
* @function * @function
* @param {String} code The compiled PaperScript code. * @param {String} code The PaperScript code.
* @param {PaperScript} scope The scope in which the code is executed. * @param {PaperScript} scope The scope in which the code is executed.
* @return {Object} The result of the code evaluation. * @return {Object} The result of the code evaluation.
*/ */
function evaluate(code, scope) { function evaluate(code, scope) {
/*#*/ if (options.browser) {
// See if it's a script tag or a string
if (typeof code !== 'string') {
// If a canvas id is provided, create a project for it now,
// so the active project is defined.
var canvas = PaperScript.getAttribute(code, 'canvas');
if (canvas = canvas && document.getElementById(canvas)) {
scope.setup(canvas);
}
if (code.src) {
// If we're loading from a source, request that first and then
// run later.
return request(code.src, scope);
} else {
// We can simply get the code form the script tag.
code = code.innerHTML;
}
}
/*#*/ } // options.browser
// Set currently active scope. // Set currently active scope.
paper = scope; paper = scope;
var view = scope.view, var view = scope.view,
@ -242,8 +224,7 @@ var PaperScript = this.PaperScript = new function() {
} }
function load() { function load() {
var scripts = document.getElementsByTagName('script'), var scripts = document.getElementsByTagName('script');
count = 0;
for (var i = 0, l = scripts.length; i < l; i++) { for (var i = 0, l = scripts.length; i < l; i++) {
var script = scripts[i]; var script = scripts[i];
// Only load this script if it not loaded already. // Only load this script if it not loaded already.
@ -253,15 +234,21 @@ var PaperScript = this.PaperScript = new function() {
// Produce a new PaperScope for this script now. Scopes are // Produce a new PaperScope for this script now. Scopes are
// cheap so let's not worry about the initial one that was // cheap so let's not worry about the initial one that was
// already created. // already created.
// Define an id for each paperscript, so its scope can be // Define an id for each PaperScript, so its scope can be
// retrieved through PaperScope.get(). // retrieved through PaperScope.get().
var scope = new PaperScope(script.getAttribute('id') // If a canvas id is provided, pass it on to the PaperScope
|| script.src || ('paperscript-' + (count++))); // so a project is created for it now.
// Make sure the tag also has this id now. If it already had an var canvas = PaperScript.getAttribute(script, 'canvas');
// id, we're not changing it, since it's the first option we're canvas = canvas && document.getElementById(canvas);
// trying to get an id from above. var scope = new PaperScope(canvas, script);
script.setAttribute('id', scope.id); if (script.src) {
evaluate(script, scope); // If we're loading from a source, request that first and then
// run later.
request(script.src, scope);
} else {
// We can simply get the code form the script tag.
evaluate(script.innerHTML, scope);
}
// Mark script as loaded now. // Mark script as loaded now.
script.setAttribute('data-paper-loaded', true); script.setAttribute('data-paper-loaded', true);
} }