Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

paper.js how to set up multiple canvases using only javascript

I'm trying to use paper.js in a webapp, but I've been unable to get it to work with multiple canvases. It's like the scopes are getting mixed up between the canvases, so when I intend to draw on canvas 1, it appears on canvas 2.

In each view, I'm initialize the paper like this:

this.mypaper = new paper.PaperScope();
this.mypaper.setup($("myCanvasId")[0]);

When I create new paper objects, I use what should be the local scope:

var circle = new this.mypaper.Path.Circle(10, 10, 5);

However, when I create a circle in view1, it draws it in view2 instead.

I've done a lot of reading, but I still haven't found a clear explanation of how to setup multiple paperscopes or how to isolate views from each other.

Does anyone know how to use multiple canvases with paper.js correctly?


EDIT: I've created a jsFiddle to illustrate the problem: http://jsfiddle.net/94RTX/1/

like image 237
frodo2975 Avatar asked May 31 '13 20:05

frodo2975


4 Answers

In order to more explicitly manage which paperscope you are adding items to, you might consider setting the option insertItems to false.

  var paper1 = new paper.PaperScope();
  paper1.setup(canvasElement);
  paper1.settings.insertItems = false; 

That way, when you create new paper items, they are not automatically added to the paper. So, no matter which scope your paper item was created in, you still decide to add it to one paper or another. For example, you can theoretically do:

  // create a second scope 
  var paper2 = new paper.PaperScope();
  // create a circle in the first scope
  var myCircle = new paper1.Path.Circle(new paper1.Point(100, 70), 50);
  myCircle.fillColor = 'black';
  // add that circle to the second scope's paper 
  paper2.project.activeLayer.addChild(myCircle);
like image 178
danyamachine Avatar answered Sep 26 '22 01:09

danyamachine


I haven't worked with Paper.js extensively, but it seems that each call to Path isn't using the PaperScope from which it's being accessed, but the global paper object. So if you overwrite paper to your desired PaperScope before each instantiation it should work.

See my updated fiddle.

like image 15
freejosh Avatar answered Oct 29 '22 02:10

freejosh


I actually solve this a bit differently:

var scope1 = new paper.PaperScope();
var scope2 = new paper.PaperScope();

When I want to draw in scope1:

scope1.activate();
// now I draw

Similarly when I want to draw in scope 2

scope2.activate();
// now I draw
like image 10
Digant C Kasundra Avatar answered Oct 29 '22 02:10

Digant C Kasundra


Use arrays to separated your papers.

this.mypapers = []

var mypaper = new paper.PaperScope();
mypaper.setup($("myCanvasId")[0]);

mypapers.push(mypaper);

mypaper = new paper.PaperScope();
mypaper.setup($("myCanvasId")[1]);

mypapers.push(mypaper);

var circle = new this.mypapers[0].Path.Circle(10,10,5);
var circle2 = new this.mypapers[1].Path.Circle(10,10,10);

EDIT: I've update your js fiddle: http://jsfiddle.net/94RTX/3/

Apparently each setup erase the previous one, so the solution is to do it in this order:

setup canvas 1-> draw canvas 1 -> setup canvas 2 -> draw canvas 2
like image 4
Antoine Avatar answered Oct 29 '22 00:10

Antoine