2013-05-31 33 views
10

Tôi đang cố gắng sử dụng paper.js trong ứng dụng web, nhưng tôi không thể làm cho nó hoạt động với nhiều canvas. Nó giống như phạm vi đang nhận được lẫn lộn giữa các bức tranh sơn dầu, vì vậy khi tôi có ý định để vẽ trên vải 1, nó xuất hiện trên vải 2.paper.js cách thiết lập nhiều canvas chỉ sử dụng javascript

Trong mỗi quan điểm, tôi khởi tạo giấy như thế này:

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

khi tôi tạo các đối tượng giấy mới, tôi sử dụng những gì nên phạm vi địa phương:

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

Tuy nhiên, khi tôi tạo ra một vòng tròn trong view1, nó vẽ nó trong View2 để thay thế.

Tôi đã thực hiện rất nhiều bài đọc, nhưng tôi vẫn chưa tìm thấy giải thích rõ ràng về cách thiết lập nhiều giấy tờ hoặc cách tách biệt chế độ xem với nhau.

Có ai biết cách sử dụng nhiều canvases với paper.js chính xác không?


EDIT: Tôi đã tạo một jsFiddle để minh họa cho vấn đề: http://jsfiddle.net/94RTX/1/

Trả lời

11

tôi đã không làm việc với Paper.js rộng rãi, nhưng dường như mỗi cuộc gọi đến Path không sử dụng PaperScope mà từ đó nó được truy cập, nhưng đối tượng paper toàn cầu. Vì vậy, nếu bạn ghi đè paper vào PaperScope mong muốn của mình trước mỗi lần khởi tạo, nó sẽ hoạt động.

See my updated fiddle.

+0

Đó là nó! Cảm ơn! – frodo2975

+0

Điều này không hoạt động nếu bạn gọi một sự kiện thay đổi kích thước sau này ... Sẽ cố gắng để tạo ra một fiddle – rassoh

+0

Tôi cảm thấy nó đáng nói đến mô hình tôi sử dụng. Nó là để có một hàm accessor giấy, như 'hàm getPaper() {return window.paper = mypaper; } 'Bằng cách đó bạn có thể chắc chắn bất cứ khi nào bạn sử dụng giấy, biến toàn cầu sẽ được thiết lập một cách thích hợp. –

4

Sử dụng mảng để tách giấy tờ của bạn.

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: Tôi đã cập nhật js của bạn fiddle: http://jsfiddle.net/94RTX/3/

Rõ ràng mỗi thiết lập xóa trước đó, vì vậy giải pháp là để làm điều đó theo thứ tự này:

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

Hmmm, dường như vẫn không hoạt động. Tôi đã cập nhật câu hỏi ban đầu của tôi với một jsfiddle để bạn có thể thấy những gì tôi đang nói về. – frodo2975

+0

Tôi đã chỉnh sửa câu trả lời của mình – Antoine

+2

Thật không may, cách này chỉ hoạt động nếu bạn thực hiện tất cả mã vẽ của mình trong một bước. Vì tôi cũng có các cuộc gọi lại không đồng bộ cần phải vẽ mọi thứ, làm theo cách này không phải là một lựa chọn. – frodo2975

1

Tôi nghĩ rằng tôi đã tìm thấy các giải pháp: Tôi mở rộng fiddle từ @freejosh cũng làm việc với callbacks (ví dụ như thay đổi kích thước): Bí quyết là để tái nạp phạm vi đúng bên trong hàm 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); 
}); 

Xin lưu ý rằng tôi cũng bao gồm tương tác đơn giản với các vòng kết nối, cũng để kiểm tra hành vi đúng ở đó.

5

Tôi thực sự giải quyết này một chút khác nhau:

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

Khi tôi muốn vẽ trong scope 1:

scope1.activate(); 
// now I draw 

Tương tự như vậy khi tôi muốn vẽ trong phạm vi 2

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

Cảm ơn, nó đã làm việc cho tôi. –

1

Để quản lý rõ ràng hơn những giấy tờ bạn đang thêm các mục vào, bạn có thể cân nhắc đặt tùy chọn insertItems đến false.

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

Bằng cách đó, khi bạn tạo các mục giấy mới, chúng không tự động được thêm vào giấy. Vì vậy, không có vấn đề mà phạm vi mục giấy của bạn đã được tạo ra trong, bạn vẫn quyết định thêm nó vào một giấy hoặc khác. Ví dụ: về lý thuyết bạn có thể làm:

// 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); 
Các vấn đề liên quan