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
* Paper context. When working with PaperScript, these scopes are automatically
* created and their fields and methods become part of the global scope. When
* working with normal JavaScript files, {@code PaperScope} objects need to be
* manually created and handled.
* The global {@link paper} object is simply a reference to the
* currently active {@code PaperScope}.
* created, and through clever scoping the fields and methods of the active
* scope seem to become part of the global scope. When working with normal
* JavaScript code, {@code PaperScope} objects need to be manually created and
* handled.
* 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# */{
initialize: function(id) {
this.project = null;
this.projects = [];
this.view = null;
/**
* Creates a PaperScope object and an empty {@link Project} for it. If a
* 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.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.tools = [];
this.id = id;
PaperScope._scopes[id] = this;
var obj = script || canvas;
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;
},
/**
* 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
* 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() {
this.clear();
delete PaperScope._scopes[this.id];
delete PaperScope._scopes[this._id];
},
_needsRedraw: function() {
@ -147,6 +160,7 @@ var PaperScope = this.PaperScope = Base.extend(/** @lends PaperScope# */{
statics: /** @lends PaperScope */{
_scopes: {},
_id: 0,
/**
* 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
* canvas setup, tool creation and handlers automatically.
* Evaluates parsed PaperScript code in the passed {@link PaperScope}
* object. It also handles canvas setup, tool creation and handlers
* automatically for us.
*
* @name PaperScript.evaluate
* @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.
* @return {Object} The result of the code evaluation.
*/
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.
paper = scope;
var view = scope.view,
@ -242,8 +224,7 @@ var PaperScript = this.PaperScript = new function() {
}
function load() {
var scripts = document.getElementsByTagName('script'),
count = 0;
var scripts = document.getElementsByTagName('script');
for (var i = 0, l = scripts.length; i < l; i++) {
var script = scripts[i];
// 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
// cheap so let's not worry about the initial one that was
// 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().
var scope = new PaperScope(script.getAttribute('id')
|| script.src || ('paperscript-' + (count++)));
// Make sure the 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.
script.setAttribute('id', scope.id);
evaluate(script, scope);
// If a canvas id is provided, pass it on to the PaperScope
// so a project is created for it now.
var canvas = PaperScript.getAttribute(script, 'canvas');
canvas = canvas && document.getElementById(canvas);
var scope = new PaperScope(canvas, script);
if (script.src) {
// 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.
script.setAttribute('data-paper-loaded', true);
}