paper.js如何仅使用javascript设置多个画布

时间:2013-05-31 20:57:10

标签: javascript canvas paperjs

我正在尝试在webapp中使用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/

7 个答案:

答案 0 :(得分:13)

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

See my updated fiddle

答案 1 :(得分:8)

我实际上解决了这个问题:

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

当我想在scope1中绘图时:

scope1.activate();
// now I draw

同样当我想画范围2时

scope2.activate();
// now I draw

答案 2 :(得分:3)

使用数组分隔你的论文。

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

答案 3 :(得分:1)

我认为我找到了解决方案:我将@freejosh的小提琴扩展为也可以使用回调(例如resize):诀窍是在回调函数中重新获取正确的范围:

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

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

答案 4 :(得分:1)

为了更明确地管理您要添加项目的papercope,您可以考虑将选项insertItems设置为false

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

答案 5 :(得分:1)

@freejosh的答案非常适合10.2,但在升级到最新版本(截至目前为12.2)时,小提琴手仍在使用一块画布:

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

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

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

<svg class="svg-object" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1923 643" preserveAspectRatio="xMinYMin meet">
  <path id="motionPath" fill="none" stroke="#000000" stroke-miterlimit="10"
    d="M1438.8,348.8c6.2,189.4-75.3,34.5-157.8,28.3c-515.1,38.8-757.8,54.5-849.3,72.8
    c-17.9,10.9-13.4,91.9-14.9,155.8"
  />
  <g id="vehicle" stroke-width="2" stroke="red">
    <path id="rightside" d="M13,2c-0.6,0-1-0.4-1-1s0.4-1,1-1s8,0.4,8,1S13.6,2,13,2z"/>
    <path id="leftside" d="M8,2C7.4,2,0,1.6,0,1s7.4-1,8-1s1,0.4,1,1S8.6,2,8,2z"/>
  </g>
     <!-- Two dash move forward 10s -->
  <animateMotion id="movement_forward"
          xlink:href="#vehicle"
          dur="10s"
          begin="0;movement_back.end"
          keyPoints="0;0.2;0.4;0.8;1"
          keyTimes="0;0.495;0.6;0.75;1"
          calcMode="linear"
                   > 
    <mpath xlink:href="#motionPath" />
  </animateMotion>  
      <!-- One dash goes back 10 seconds -->
      <animateMotion id="movement_back"
          xlink:href="#rightside"
          dur="10s"
          begin="movement_forward.end"
          keyPoints="1;0.8;0.4;0.2;0"
          keyTimes="0;0.495;0.6;0.75;1"
          calcMode="linear"
                   > 
    <mpath xlink:href="#motionPath" />
  </animateMotion>
  
 
</svg>

答案 6 :(得分:0)

实际上,您只需要一个 Paperscope

This tutorial 说:

<块引用>

直接使用 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