So I am trying to create a project with two canvas elements, each with its own paperscript, and with buttons on the outside of each that control certain functions within both.
Under the documentation under Paperscript, it says:
Please note: When including more than one PaperScript in a page, each script will run >in its own scope and will not see the objects and functions declared in >the others. For PaperScript to communicate with other PaperScript or >JavaScript code, see the tutorial about PaperScript Interoperability.
... which is unfortunate because that tutorial reads as follows:
Coming very soon!
I've gotten stuck very quickly in this process. I've tried putting functions in global scope, calling them from outside their canvas, and seeing them print on the wrong canvas. I've tried exporting functions via a module and it seems to run the function (?!?!). And worst, the 'paper.projects' object is an array with one(!) project in it, the first canvas.
So I'm stumped.
Anyone know how to do this?
EDIT: So apparently there is this answer but I don't see how that gets me being able to call functions in the PaperScript scope from global scope scripts.
That just seems like a script to call global functions in the PaperScope, which doesn't work for me if I'm trying to make outside buttons do things.
Clearly I'm missing something.
SECOND EDIT: I have played around with various global functions, either in window.global or just sitting by themselves with no var declaration... but what seems to happen is that when I try to call a function which I have defined, say as:
globals.makecircle = function () {
var o = new Path.Circle({
radius: 50,
center: new Point (200,200)
})
}
in the main scope, it will just as soon run in the wrong window as the correct window. Also there is an incredible delay before it runs which I can't figure out.
THIRD EDIT: For clarity.
I have firstcanvas.js
attached to canvas1
in my HTML, I have secondcanvas.js
attached to canvas2
. Both are referenced as paperscript type, as:
<script type="text/paperscript" src="scripts/firstcanvas.js" canvas="canvas1"></script>
<script type="text/paperscript" src="scripts/secondcanvas.js" canvas="canvas2"></script>
I create window.globals
object as Jurg suggests. I call it from main.js with a button, such as:
window.globals = {}
`$('document').ready($('#dfs').on('click', window.globals.makecircle))`
I add this function to globals in firstcanvas.js
as above.
If I have most recently clicked on canvas2, clicking on the button with id='DFS'
will cause the function to run, extremely delayed, on canvas2.
And paper.projects
does not list both projects, so I can't use the activate()
functions.
Okay! SOLVED!!!
Here's how to reference/activate PaperScript-created scopes from the global scope. Although there is no user-accessible array of scopes (that I know of),
PaperScope.get(id)
will retrieve them. For some reason I findPaperScope.get(0)
already populated, and my two canvas/PaperScript elements actually referring to scopes with ids 1 and 2.Therefore:
Then, in any function where I want to do something on my first canvas:
The last line is because
paper.js
won't automatically update a view that the user is not interacting with.Thanks to Jurg Lehni for the hint to use
.activate()
.PS Make sure that your paperscript objects are created before using
PaperScope.get
. I used good 'ol JQuery$('document').ready()
for this...PPS Another little hit from Jurg Lehni himself: Inside a PaperScript,
this
will point to the current scope. You could use that and store it in the global object.