2013-05-31 27 views
10

Próbuję użyć paper.js w webappie, ale nie udało mi się go uruchomić z wieloma płótnami. To jak zakresy są coraz pomieszane między płócien, więc kiedy mam zamiar wyciągnąć na płótnie 1, wydaje się na płótnie 2.paper.js jak ustawić wiele płócien tylko za pomocą javascript

W każdym widoku, jestem zainicjować papier tak:

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

kiedy tworzyć nowe obiekty papierowe, używam tego, co powinno być lokalny zakres:

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

jednak, kiedy utworzyć krąg w view1, czerpie ją w view2 zamiast.

Zrobiłem dużo czytania, ale nadal nie znalazłem jasnego wyjaśnienia, jak skonfigurować wiele workflow lub jak izolować widoki od siebie nawzajem.

Czy ktoś wie, jak poprawnie używać wielu płótna z plikiem paper.js?


EDIT: Utworzyłem jsFiddle do zilustrowania problemu: http://jsfiddle.net/94RTX/1/

Odpowiedz

11

I nie pracowałem intensywnie z Paper.js, ale wydaje się, że każde wywołanie do Path nie używa PaperScope, z którego jest uzyskiwany dostęp, ale globalnego obiektu paper. Więc jeśli nadpisasz paper do żądanego PaperScope przed każdą instancją, powinna działać.

See my updated fiddle.

+0

To było to! Dzięki! – frodo2975

+0

To nie działa, jeśli wywołasz zdarzenie zmiany rozmiaru później ... Spróbuję stworzyć skrzypce – rassoh

+0

Czuję, że warto wspomnieć o używanym wzorze. Ma mieć funkcję dostępu do papieru, np. 'Function getPaper() {return window.paper = mypaper; } 'W ten sposób możesz być pewien, że gdy użyjesz papieru, zmienna globalna zostanie odpowiednio ustawiona. –

4

Używaj tablic do oddzielonych swoimi papierami.

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: mam zaktualizować skrzypiec JS: http://jsfiddle.net/94RTX/3/

Podobno każda konfiguracja skasować poprzednią, więc rozwiązanie jest, aby zrobić to w tej kolejności:

setup canvas 1-> draw canvas 1 -> setup canvas 2 -> draw canvas 2 
+0

Hmmm, nadal nie działa. Zaktualizowałem moje oryginalne pytanie za pomocą jsfiddle, dzięki czemu możesz zobaczyć, o czym mówię. – frodo2975

+0

Edytowałem moją odpowiedź – Antoine

+2

Niestety, działa to tylko wtedy, gdy wykonujesz cały kod rysunkowy w jednym kroku. Ponieważ mam również asynchroniczne wywołania zwrotne, które wymagają rysowania, nie jest to opcja wykonania tego w ten sposób. – frodo2975

1

Chyba znalazłem rozwiązanie: I rozszerzył skrzypce z @freejosh również pracować z wywołań zwrotnych (np zmiana rozmiaru): Sztuką jest, aby ponownie pobrać prawidłowy zakres wewnątrz funkcji callback:

http://jsfiddle.net/rassoh/mx9n3vsf/7/

var mypapers = []; 

initPaper(0, $("#canvas1")[0]); 
initPaper(1, $("#canvas2")[0]); 

function initPaper(id, canvasElement) { 
    var mousePosition = new paper.Point(0,0); 
    mypapers[id] = new paper.PaperScope(); 
    paper = mypapers[id]; 
    paper.setup(canvasElement); 
    var myCircle; 

    createCircle = function() { 
     if("undefined" !== typeof myCircle) { 
      myCircle.remove(); 
     } 
     // this function is called on resize, so we have to re-fetch the scope! 
     paper = mypapers[id]; 
     myCircle = new paper.Path.Circle(30, 30, 20); 
     var lightRed = new paper.Color(1, 0.5, 0.5); 
     var lightBlue = new paper.Color(0.5, 0.5, 1); 
     myCircle.style = { 
      fillColor: id === 0 ? lightRed : lightBlue, 
      strokeColor: "black" 
     }; 
    } 
    createCircle(); 

    var tool = new paper.Tool(); 
    tool.onMouseMove = function(event) { 
     mousePosition = event.lastPoint; 
    }; 
    paper.view.onFrame = function() { 
     if("undefined" === typeof myCircle) { 
      return; 
     } 
     var dist = mousePosition.subtract(myCircle.position); 
     dist = dist.divide(3); 
     myCircle.position = myCircle.position.add(dist); 
    }; 
    paper.view.onResize = function() { 
     createCircle(); 
    }; 
} 

$(window).resize(function() { 
    var width = $(".container").width()/2; 
    var height = $(".container").height(); 
    // this automatically triggeres paper's onResize event registered above 
    mypapers[0].view.viewSize = new paper.Size(width, height); 
    mypapers[1].view.viewSize = new paper.Size(width, height); 
}); 

Zwróć uwagę, że dodałem również prostą interakcję z kręgami, aby przetestować poprawne zachowanie.

5

I rzeczywiście rozwiązać ten problem nieco inaczej:

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

Kiedy chcę rysować w scope1:

scope1.activate(); 
// now I draw 

Podobnie gdy chcę rysować w zakresie 2

scope2.activate(); 
// now I draw 
+1

Dzięki, zadziałało to dla mnie. –

1

Aby bardziej precyzyjnie zarządzać tym, który zestaw zadań do drukowania dodajesz, możesz ustawić opcję insertItems do false.

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

W ten sposób, po utworzeniu nowych artykułów papierowych, nie są one automatycznie dodawane do papieru. Bez względu na to, w jakim zakresie został utworzony element papierowy, nadal chcesz dodać go do jednego lub drugiego papieru. Na przykład teoretycznie można:

// 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);