Lee Woodall
Lee Woodall

Reputation: 21

p5.js mousePressed line animation

In p5.js I'm trying to create an animation where the bottom point of the lines smoothly (5px per frame) move to the bottom left corner of the canvas when the mouse is pressed. I can get them to the point they need to get to with lines.align but they instantly move there instead of animating.

    let lines = []

    function setup() {
      createCanvas(600, 400);
      for(let i = 0; i < 150; i++) {
          lines[i] = new Line(random(600), 0, random(600), 400, random(149,212), random(89, 146), 1);
        }
    }

    function draw() {
      background(32, 44, 57);
      for(let i = 0; i < lines.length; i++){
        lines[i].show();
      }
    }

    function mousePressed() {
      for(let i = 0; i < lines.length; i++){
        lines[i].align();
      }
    }

    class Line {
      constructor(xStart, yStart, xFinish, yFinish, g, b, w) {
        this.xStart = xStart;
        this.yStart = yStart;
        this.xFinish = xFinish;
        this.yFinish = yFinish;
        this.g = g;
        this.b = b;
        this.w = w;
      }

      show() {
        stroke(242, this.g, this.b);
        strokeWeight(this.w);
        line(this.xStart, this.yStart, this.xFinish, this.yFinish);
      }

      align() {
        while (this.xFinish > 0) {
          this.xFinish = this.xFinish - 5;
        }
      }
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>

Upvotes: 2

Views: 634

Answers (1)

George Profenza
George Profenza

Reputation: 51837

You're using a blocking while loop which is why visually you see a jump from the lines' start to end positions.

One option is to use a condition and increment the value in draw():

let lines = []

    function setup() {
      createCanvas(600, 400);
      for(let i = 0; i < 150; i++) {
          lines[i] = new Line(random(600), 0, random(600), 400, random(149,212), random(89, 146), 1);
        }
    }

    function draw() {
      background(32, 44, 57);
      for(let i = 0; i < lines.length; i++){
        lines[i].align();
        lines[i].show();
      }
    }

    class Line {
      constructor(xStart, yStart, xFinish, yFinish, g, b, w) {
        this.xStart = xStart;
        this.yStart = yStart;
        this.xFinish = xFinish;
        this.yFinish = yFinish;
        this.g = g;
        this.b = b;
        this.w = w;
      }

      show() {
        stroke(242, this.g, this.b);
        strokeWeight(this.w);
        line(this.xStart, this.yStart, this.xFinish, this.yFinish);
      }

      align() {
        if (this.xFinish > 0) {
          this.xFinish = this.xFinish - 5;
        }
      }
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>

You might want to also check out lerp() to interpolation between start and end positions.

Additionally, if you need more control over timing/easing/etc you can use something like TweenLite to do the interpolation for you. (It is a good exercise though to get a hang of incrementing values/interpolating/tweening manually first through)

Upvotes: 2

Related Questions