2013-05-31 74 views
10

我想在webapp中使用paper.js,但我一直無法讓它與多個畫布一起工作。這就像範圍越來越畫布之間混合起來,所以當我打算在畫布上繪製1,它出現在畫布2.paper.js如何設置多個畫布只使用javascript

在每個視圖中,我初始化這樣的文件:

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

當我創建新的文件對象,我用的應該是當地範圍:

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

然而,當我在廠景創建一個圓,它吸引它在視圖2代替。

我已經做了大量的閱讀,但我還沒有找到一個清楚的解釋如何設置多個paperscopes或如何隔離彼此的意見。

有誰知道如何正確使用paper.js的多個畫布?


編輯:我創建了一個的jsfiddle來說明這個問題:http://jsfiddle.net/94RTX/1/

回答

11

我還沒有廣泛使用Paper.js,但似乎每個Path的調用都沒有使用它被訪問的PaperScope,而是全局的paper對象。因此,如果您在每個實例化之前將paper覆蓋到您所需的PaperScope上,它應該可以工作。

See my updated fiddle

+0

就是這樣!謝謝! – frodo2975

+0

如果您稍後再調用一個調整大小的事件,這不起作用...將嘗試創建一個小提琴 – rassoh

+0

我覺得值得一提的是我使用的模式。它有一個紙張存取器函數,比如'function getPaper(){return window.paper = mypaper; }'這樣你就可以確定每當你使用紙時,全局變量將被適當設置。 –

4

使用數組來分開你的論文。

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

編輯:我已經更新您的JS提琴: http://jsfiddle.net/94RTX/3/

顯然,每個設置擦除前一個,所以解決的辦法就是做這個順序:

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

嗯,似乎仍然沒有工作。我用jsfiddle更新了我的原始問題,這樣你就可以看到我在說什麼了。 – frodo2975

+0

我編輯了我的答案 – Antoine

+2

不幸的是,這種方式只適用於您一步完成所有繪圖代碼的情況。由於我也有需要繪製事物的異步回調,因此這樣做並不是一種選擇。 – frodo2975

1

我想我找到了解決辦法:我從擴大的@freejosh小提琴也有回調的工作(如調整大小):關鍵是要重新獲取的回調函數內的正確範圍:

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

請注意,我還包括與圈子的簡單交互,以測試其中的正確行爲。

5

我其實解決這個問題有點不同:

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

當我想在scope1畫:

scope1.activate(); 
// now I draw 

同樣,當我想在範圍2

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

謝謝,它爲我工作。 –

1

畫爲了更明確地管理要添加項目的哪個paperscope,您可以考慮設置選項insertItemsfalse

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

這樣,當你創建新的紙製品,它們不會自動添加到該文件。因此,無論您的紙張項目創建在哪個範圍內,您仍然決定將其添加到一張紙或另一張紙上。例如,你可以理論上這樣做:

// 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); 
相關問題