13

我正在尝试在 web 应用程序中使用 paper.js,但我无法让它与多个画布一起使用。就像画布之间的范围混淆了,所以当我打算在画布 1 上绘图时,它会出现在画布 2 上。

在每个视图中,我都像这样初始化论文:

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

当我创建新的纸质对象时,我使用本地范围:

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

但是,当我在 view1 中创建一个圆圈时,它会在 view2 中绘制它。

我做了很多阅读,但我仍然没有找到关于如何设置多个纸镜或如何将视图彼此隔离的清晰解释。

有谁知道如何正确使用 paper.js 的多个画布?


编辑:我创建了一个 jsFiddle 来说明问题:http: //jsfiddle.net/94RTX/1/

4

7 回答 7

14

我没有广泛使用 Paper.js,但似乎每次调用Path都不是使用PaperScope它被访问的对象,而是使用全局paper对象。因此,如果您paper在每次实例化之前覆盖所需的 PaperScope,它应该可以工作。

请参阅我更新的小提琴

于 2013-06-03T16:21:06.950 回答
10

我实际上以不同的方式解决了这个问题:

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

当我想在 scope1 中绘制时:

scope1.activate();
// now I draw

同样,当我想绘制范围 2 时

scope2.activate();
// now I draw
于 2016-11-19T07:08:37.527 回答
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
于 2013-05-31T22:18:38.527 回答
4

为了更明确地管理要添加项目的纸张范围,您可以考虑将选项设置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);
于 2017-01-28T00:48:20.040 回答
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 );
});

请注意,我还包括了与圈子的简单交互,以测试那里的正确行为。

于 2015-05-01T11:32:44.247 回答
1

@freejosh 的答案适用于 10.2,但升级到最新版本(截至目前为 12.2)时,小提琴仍然重新使用一个画布:

http://jsfiddle.net/ecneto/86qckn2h/1/

这是一个简单的修复,您可以降级,也可以使用 scope.activate(),这比覆盖纸要好得多:

http://jsfiddle.net/ecneto/n91rdp6z/2/

mypapers[0].activate();
var circle1 = new paper.Path.Circle(30, 30, 20);
circle1.style = {
    fillColor: new paper.Color(1, .5, .5),
    strokeColor: "black"
};

mypapers[1].activate();
var circle2 = new paper.Path.Circle(60, 60, 20);
circle2.style = {
    fillColor: new paper.Color(.5, .5, 1),
    strokeColor: "black"
};
于 2019-12-15T17:47:56.660 回答
0

实际上,您只需要一个Paperscope.

本教程说:

直接使用 JavaScript 时,大多数情况下只需要一个作用域。在此范围内,仍然可以通过使用 new Project() 和 new View(canvas) 构造函数创建多个项目或视图来处理它们。

paper.setup('canvas1')
paper.setup('canvas2')

paper.projects[0].activate()
// canvas1 is activated
// draw something on canvas1

paper.projects[1].activate()
// canvas2 is activated
// draw something on canvas2

于 2021-03-26T09:05:53.873 回答