Paper.js不会绘制多个形状

时间:2017-04-01 22:25:16

标签: javascript paperjs

我是JavaScript的新手,所以我在寻求帮助。我正在尝试创建一个简单的太阳系模拟,它表示为围绕一个大圆(太阳)移动的几个小圆圈(行星)。我使用Paper.js来创建动画。

我创建了两个类:Star和Planet。 Star类有draw()方法绘制星星,Planet类有motion()方法使行星移动。

问题在于,当我创建多个对象并调用它们的draw()/ motion()方法,然后尝试运行脚本时,我创建的最后一个对象是唯一要绘制/动画的对象。

例如,在此代码中:

var sun = new Star("Sun", 400, 400, 50, '#fff250');
sun.draw();


var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
earth.motion();

var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
mars.motion();

mars.motion()会正常工作,但其他两种方法都会被忽略。如果我删除此方法,将出现地球等等。

以下是完整代码:

function Star(name, xCoordinate, yCoordinate, radius, color) {
    this.name = name;
    this.xCoordinate = xCoordinate;
    this.yCoordinate = yCoordinate;
    this.radius = radius;
    this.color = color;


    var canvas = document.getElementById("canvas1");
    paper.setup(canvas);

    this.draw = function () {

        var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
        circle.fillColor = color;
    }

}

function Planet(name, parentStar, distanceFromStar, radius, period, color) {
    this.name = name;
    this.parentStar = parentStar;
    this.distanceFromStar = distanceFromStar;
    this.radius = radius;
    this.period = period;
    this.color = color;

    var xCoordinate = parentStar.xCoordinate + distanceFromStar;
    var yCoordinate = parentStar.yCoordinate + distanceFromStar;

    var canvas = document.getElementById("canvas1");
    paper.setup(canvas);

    this.motion = function () {


        var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
        circle.fillColor = color;

        paper.view.onFrame = function (event) {

            circle.position.x = parentStar.xCoordinate - distanceFromStar * Math.cos(period * event.time);
            circle.position.y = parentStar.yCoordinate - distanceFromStar * Math.sin(period * event.time);
        }

    }
}

window.onload = function() {
    var sun = new Star("Sun", 400, 400, 50, '#fff250');
    sun.draw();


    var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
    earth.motion();

    var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
    mars.motion();

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="paper-core.js"></script>
    <script src="solar-system.js"></script>
</head>
<body>
<canvas id="canvas1" resize="" style="user-select: none; touch-action: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="800" height="800" ></canvas>
</body>
</html>

我认为可能的原因是我这样做了

var canvas = document.getElementById("canvas1");
paper.setup(canvas);

每次我创建一个新对象,但我不确定。请帮忙。提前谢谢。

1 个答案:

答案 0 :(得分:0)

你对这个问题的假设是正确的。

每次绘制元素时都要设置整个画布。

您只需要设置一次(刚刚从绘制方法中删除了设置并将其添加到window.onload )。

另一个问题是您将每个行星更新代码分配为paper.view.onFrame。但它只能包含一个功能。为此我创建了一个列表,其中每个行星的更新函数去,然后在paper.view.onFrame i迭代数组并执行每个行星函数。

以下是包含更改的代码

var planetList = [];

function Star(name, xCoordinate, yCoordinate, radius, color, canvas) {
  this.name = name;
  this.xCoordinate = xCoordinate;
  this.yCoordinate = yCoordinate;
  this.radius = radius;
  this.color = color;

  this.draw = function() {

    var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
    circle.fillColor = color;
  }

}

function Planet(name, parentStar, distanceFromStar, radius, period, color, canvas) {
  this.name = name;
  this.parentStar = parentStar;
  this.distanceFromStar = distanceFromStar;
  this.radius = radius;
  this.period = period;
  this.color = color;

  var xCoordinate = parentStar.xCoordinate + distanceFromStar;
  var yCoordinate = parentStar.yCoordinate + distanceFromStar;

  this.motion = function() {


    var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
    circle.fillColor = color;
    planetList.push( function(event) {

      circle.position.x = parentStar.xCoordinate - distanceFromStar * Math.cos(period * event.time);
      circle.position.y = parentStar.yCoordinate - distanceFromStar * Math.sin(period * event.time);
    });
  }
}

window.onload = function() {
  var canvas = document.getElementById("canvas1");
  paper.setup(canvas);

  var sun = new Star("Sun", 400, 400, 50, '#fff250', );
  sun.draw();


  var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
  earth.motion();

  var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
  mars.motion();
  
  paper.view.onFrame = function(event){
    var pLen = planetList.length,
        p;
    for (p=0;p<pLen;p++){
      planetList[p](event);
    }
  }

}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.10.3/paper-full.min.js"></script>
</head>

<body>
  <canvas id="canvas1" resize="" style="user-select: none; touch-action: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="800" height="800"></canvas>
</body>

</html>