Ускорьте анимацию Starfield Canvas и управляйте ею

Я пытаюсь создать анимацию холста звездного поля. Он имеет фиксированное значение скорости, поэтому звезды движутся с одинаковой скоростью, но теперь я хочу запустить его, когда звезды не движутся, и когда вы нажимаете кнопку, я хочу запускать его медленно, а затем постепенно увеличивать скорость, а затем снова замедляться и останавливаться. Как мне этого добиться?

Скорости должны быть как в этом примере https://www.shadertoy.com/view/Xdl3D2

<!DOCTYPE html>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    <canvas id="c" width="900px" height="700px"></canvas>
    
    <script type="text/javascript">
    const canvas = document.getElementById('c');
    const c = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    window.addEventListener('wheel', (event) => {
      if (event.deltaY < 0) speed *= 1.1;
      else speed *= 0.9;
      if (speed < 0.01) speed = 0.01;
      else if (speed > 0.1) speed = 0.1;
    });
    class Star {
      constructor() {
        this.x = Math.random()*canvas.width-canvas.width/2;
        this.y = Math.random()*canvas.height-canvas.height/2;
        this.px, this.py;
        this.z = Math.random()*4;
      }
      update() {
        this.px = this.x;
        this.py = this.y;
        this.z += speed;
        this.x += this.x*(speed*0.2)*this.z;
        this.y += this.y*(speed*0.2)*this.z;
        if (this.x > canvas.width/2+50 || this.x < -canvas.width/2-50 ||
            this.y > canvas.height/2+50 || this.y < -canvas.height/2-50) {
          this.x = Math.random()*canvas.width-canvas.width/2;
          this.y = Math.random()*canvas.height-canvas.height/2;
          this.px = this.x;
          this.py = this.y;
          this.z = 0;
        }
      }
      show() {
        c.lineWidth = this.z;
        c.beginPath();
        c.moveTo(this.x, this.y);
        c.lineTo(this.px, this.py);
        c.stroke();
      }
    }
    let speed = 0.09;
    let stars = [];
    for (let i = 0; i < 1000; i++) stars.push(new Star());
    c.fillStyle = 'rgba(0, 0, 0, 0.4)';
    c.strokeStyle = 'rgb(255, 255, 255, 0.5)';
    c.translate(canvas.width/2, canvas.height/2);
    function draw() {
      requestAnimationFrame(draw);
      c.fillRect(-canvas.width/2, -canvas.height/2, canvas.width, canvas.height);
      for (let s of stars) {
        s.update();
        s.show();
      }
    }
    draw();
    </script>
    <style type="text/css">
    body {
        padding: 0;
        margin: 0;
    }
    
    canvas {
        position: absolute;
        width: 100%;
        height: 100%;
    }
    </style>
    </body>
    </html>


person Pramitha Gayan    schedule 18.05.2019    source источник
comment
Я не вижу button в вашем коде. Что вы пытались сделать? Событие wheel кажется отправной точкой.   -  person Steve O'Connor    schedule 18.05.2019


Ответы (1)


Вы должны увеличить скорость в function draw, чтобы создать эффект ускорения, и уменьшить, чтобы замедлить.

const canvas = document.getElementById('c');
const c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

class Star {
  constructor() {
    this.x = Math.random() * canvas.width - canvas.width / 2;
    this.y = Math.random() * canvas.height - canvas.height / 2;
    this.px, this.py;
    this.z = Math.random() * 4;
  }
  update() {
    this.px = this.x;
    this.py = this.y;
    this.z += speed;
    this.x += this.x * (speed * 0.2) * this.z;
    this.y += this.y * (speed * 0.2) * this.z;
    if (this.x > canvas.width / 2 + 50 || this.x < -canvas.width / 2 - 50 ||
      this.y > canvas.height / 2 + 50 || this.y < -canvas.height / 2 - 50) {
      this.x = Math.random() * canvas.width - canvas.width / 2;
      this.y = Math.random() * canvas.height - canvas.height / 2;
      this.px = this.x;
      this.py = this.y;
      this.z = 0;
    }
  }
  show() {
    c.lineWidth = this.z;
    c.beginPath();
    c.moveTo(this.x, this.y);
    c.lineTo(this.px, this.py);
    c.stroke();
  }
}

let speed = 0.005;
let speed_inc = 0.0002;
let stars = [];
for (let i = 0; i < 1000; i++) stars.push(new Star());
c.fillStyle = 'rgba(0, 0, 0, 0.4)';
c.strokeStyle = 'rgb(255, 255, 255, 1)';
c.translate(canvas.width / 2, canvas.height / 2);

function draw() {
  requestAnimationFrame(draw);
  c.fillRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
  for (let s of stars) {
    s.update();
    s.show();
  }
  if (speed >= 0.005) {
    speed += speed_inc
    if (speed > 0.1) 
      speed_inc = -0.0004;
  }
}
draw();
body {
  padding: 0;
  margin: 0;
}

canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}
<canvas id="c" width="900px" height="700px"></canvas>

person Helder Sepulveda    schedule 18.05.2019