【问题标题】:In p5.js how do I create a moving animation of an array group of lines?在 p5.js 中,如何创建一组线条的移动动画?
【发布时间】:2021-12-16 08:43:00
【问题描述】:

您好,我在 P5.js 中使用 array()randomGaussian() 创建了一个类似火花的形状。 p5.j​​s 中的代码如下所示:

let distribution = new Array(360);
let b = false;
let x, y;

function setup() {
  var cny = createCanvas(windowWidth, windowHeight);
  cnv.parent("sketchholder");
  for (let i = 0; i < distribution.length; i++) {
    distribution[i] = floor(randomGaussian(60, 50));
  }

  colorMode(HSB, 255);
  // hue, saturation, brightness
  x = width / 4;
  у = height / 3;
}

function draw() {
  background(21, 30, 10);
  translate(width / 2, height / 2);

  strokeWeight(3);
  stroke(255, 70);
  line(0, 0, -x, y);
  if (b) {
    for (let i = 0; i < distribution.length; i++) {
      rotate(TWO_PI / distribution.length);
      var colorH = random(0, 255);
      var colorS = random(100, 200);
      var colorB = random(0, 255);
      var YY = random(1, 4);
      stroke(colorH, colorS, colorB);
      strokeWeight(YY);
      strokeCap(ROUND);
      let dist = abs(distribution[i]);
      line(0, 0, dist, 0);
    }
  }
}

我希望它沿着棍子慢慢移动,并在大约 20 秒后消失,然后到达终点。我可以在 p5.js 中实现吗?或者我可以使用 p5.js 层作为 html 中的 div 创建相同的效果并在 CSS 中对其进行动画处理吗? 谢谢。

【问题讨论】:

  • 请不要发布代码截图。而是包含格式正确的代码(请参阅:meta.stackexchange.com/a/22189)。最好将您的代码发布为runnable StackSnippet
  • @Dietrich 你是那个编辑的圣人!请其他人批准待定的编辑,它需要再批准一次。
  • @PaulWheeler 我很高兴能帮上忙! ^^

标签: html css p5.js


【解决方案1】:

是的,你绝对可以用 p5.js 做到这一点。我认为尝试用 CSS 做这样的动画没有多大意义,而且无论如何都不能很好地与 p5.js 一起工作(你只能为 DOM 元素制作动画)。但是,您确实需要基本上实现自己的动画系统,在动画中的不同时间使用不同的参数值,然后自己在它们之间进行插值。这是一个基本示例:

let distribution = new Array(360);

let originX, originY;

let keyframes = [];
let keyframeTimes = [];

function setup() {
  createCanvas(windowWidth, windowHeight);
  for (let i = 0; i < distribution.length; i++) {
    distribution[i] = floor(randomGaussian(60, 50));
  }

  colorMode(HSB, 255);
  // hue, saturation, brightness
  
  // Origin relative to the center of the sketch
  originX = -width / 4;
  originY = height / 3;
  const lenX = width / 4;
  const lenY = - height / 3;
  // Add the desired parameters and times to keyframes and keyframeTimes
  keyframes.push({
    x: lenX,
    y: lenY,
    mag: 1
  });
  keyframeTimes.push(0);
  
  keyframes.push({
    x: 0.2 * lenX,
    y: 0.2 * lenY,
    mag: 0
  });
  keyframeTimes.push(20);
}

function draw() {
  background(21, 30, 10);
  translate(width / 2, height / 2);
  translate(originX, originY);

  strokeWeight(3);
  stroke(255, 70);
  
  // Find the next keyframe that we are animating towards.
  let nextKeyframeIx = keyframeTimes.findIndex(t => t > millis() / 1000);
  // Find the current/previous keyframe that we are starting from.
  // Cases to consider: the next keyframe is the first one in the list, we're in
  // between two keyframes, or there is no next keyframe
  let keyframeIx =
      nextKeyframeIx === 0 ?
        // There is no previous keyframe (we're at the beginning)
        0 :
        // If we're beyond the end of the list, just use the parameters from the
        // last keyframe
        (nextKeyframeIx > 0 ? nextKeyframeIx - 1 : keyframes.length - 1);
  
  let x, y, mag;
  
  if (keyframeIx < nextKeyframeIx) {
    // lerp between the current and next keyframe
    let kf1 = keyframes[keyframeIx];
    let kf2 = keyframes[nextKeyframeIx];
    let t1 = keyframeTimes[keyframeIx];
    let t2 = keyframeTimes[nextKeyframeIx];
    let amt = (millis() / 1000 - t1) / (t2 - t1);
    x = lerp(kf1.x, kf2.x, amt);
    y = lerp(kf1.y, kf2.y, amt);
    mag = lerp(kf1.mag, kf2.mag, amt);
  } else {
    // just use the current/previous keyframe
    let kf = keyframes[keyframeIx];
    x = kf.x;
    y = kf.y;
    mag = kf.mag;
  }
  
  // Draw a line from the origin (bottom left of the sparkler) to the current
  // x,y position of the end of the sparkler
  line(0, 0, x, y);
  // Translate to the current end of the sparkler for drawing the colored lines
  translate(x, y);
  if (mag > 0) {
    for (let i = 0; i < distribution.length; i++) {
      rotate(TWO_PI / distribution.length);
      const colorH = random(0, 255);
      const colorS = random(100, 200);
      const colorB = random(0, 255);
      const YY = random(1, 4);
      stroke(colorH, colorS, colorB);
      strokeWeight(YY);
      strokeCap(ROUND);
      let dist = abs(distribution[i]) * mag;
      line(0, 0, dist, 0);
    }
  }
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"&gt;&lt;/script&gt;

【讨论】:

    猜你喜欢
    • 2021-03-26
    • 1970-01-01
    • 2019-11-29
    • 2021-10-10
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    相关资源
    最近更新 更多