使用p5.js在路径上移动对象

时间:2016-05-03 03:45:18

标签: javascript html5-canvas p5.js

我正在尝试编写一个代码,模仿HTML画布中this video中发生的事情。

我的代码的不同之处在于,每次加载或刷新页面时,两个圆圈的半径都是随机生成的。我需要“行星”沿着各自圆圈的周长以相同的速度行进。

我正在使用p5.js绘制到画布。 p5.j​​s中是否有根据路径绘制对象的东西,在我的例子中是一个圆形的路径?

我查看了参考资料并发现了矢量,但我不太明白他们做了什么。

到目前为止我的代码:

var w = window.innerWidth;
var h = window.innerHeight;
var r1, r1;
var d;
var x1, x2, y1, y2;
var angle = Math.PI / 4;

function setup() {
    // canvas setup
    createCanvas(w, h);
    background(255);
    angleMode(RADIANS);

    // randomly generated radiuses 
    r1 = Math.floor(Math.random() * (h/2-300)) + 300;
    r2 = Math.floor(Math.random() * (200-100)) + 100;

    // drawing the two ellipses
    ellipseMode(CENTER);
    noFill();
    ellipse(w/2, h/2, r1*2, r1*2);
    ellipse(w/2, h/2, r2*2, r2*2);

}

function draw() {

    // points on the circles
    x1 = (r1 * (Math.cos(angle))) + (w/2);
    y1 = (h/2) - (r1 * (Math.sin(angle)));
    x2 = (r2 * (Math.cos(angle))) + (w/2);
    y2 = (h/2) - (r2 * (Math.sin(angle)));

    // drawing two circles at those points
    ellipseMode(CENTER);
    noStroke();
    fill('rgb(140, 140, 140)');
    ellipse(x1, y1, 20, 20);
    ellipse(x2, y2, 20, 20);

    // randomly generated color for the line
    var r = random(0, 255);
    var g = random(0, 255);
    var b = random(0, 255);
    stroke(r, g, b);
    strokeWeight(1);
    // drawing the line that connects the two points
    line(x1, y1, x2, y2);

    // animation????
    angle = angle + (10 * (Math.PI / 180));

}

最后一行的问题是它会创建evenly spaces lines,而不是视频中创建的模式。

1 个答案:

答案 0 :(得分:1)

如果两个行星以相同的角度增量移动,它们将始终保持一种关系,从而在它们之间产生均匀间隔的线。

为了使它们之间连接的线穿过中心,它们必须具有不同的增量值。您必须保持两个不同的角度值以及每个角度的步长(或速度)。

对于视频中的示例,速度比为1:2.247,基于地球和金星围绕太阳的日比例之间的真实世界关系。由于它们的速度不同,它们之间的界线现在会交叉并产生五角星形图案。

我不知道P5.js所以我在下面添加了一个简单的JavaScript示例,如果需要P5,可以将其视为伪代码。由此您将能够看到如何以可变速度计算两个位置。

实施例

snap

var ctx = c.getContext("2d"),
    ratio = 2.247,                        // earth:venus ratio 1:2.247
    angle1 = 0,                           // planet 1 current angle
    angle2 = 0,                           // planet 2 current angle
    dlt = 0.05,                           // angle step (speed)
    radius1 = 150,                        // radius path for planet 1
    radius2 = 100,                        // radius path for planet 2
    cx = c.width*0.5,                     // center canvas
    cy = c.height*0.5,
    t = 503;                              // abort animation per # of frames

ctx.strokeStyle = "rgba(0,120,255,0.5)";

(function loop() {
  var x1, y1, x2, y2;
  x1 = cx + Math.cos(angle1) * radius1;   // current (x,y) for planet 1
  y1 = cy + Math.sin(angle1) * radius1;
  x2 = cx + Math.cos(angle2) * radius2;   // current (x,y) for planet 2
  y2 = cy + Math.sin(angle2) * radius2;
  
  ctx.beginPath();                        // draw line
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
  
  angle1 += dlt;                          // increase angle planet 1
  angle2 += dlt * ratio;                  // increase angle planet 2 per ratio

  if (t--) requestAnimationFrame(loop)
})()
<canvas id=c height=300></canvas>