clearTimeout不会停止画布动画

时间:2018-04-03 19:44:46

标签: javascript html canvas settimeout cleartimeout

所以我想要启动一个简单的画布动画并停止使用切换开关。动画工作正常并启动,但clearTimeout似乎不起作用。

我确保变量“timeOut”是全局定义的,因此它应该可以访问它,这似乎是过去类似于此问题的常见建议。我在其他地方犯了错误吗?在Firefox,Chrome和Chromium上试过它。

let timeOut;

function circles() {
  let canvas = document.querySelector('canvas');
  canvas.width = document.querySelector('canvas').offsetWidth;
  canvas.height = document.querySelector('canvas').offsetHeight;
  let c = canvas.getContext('2d');
  let topRadius = 30;
  let colorArray = [
    '#ff0000',
    '#00ff00',
    '#0000ff',
  ]

  let mouse = {
    x: undefined,
    y: undefined
  }

  window.addEventListener('mousemove', function(e) {
    mouse.x = e.x;
    mouse.y = e.y;
  })

  window.addEventListener('resize', function() {
    canvas.width = document.querySelector('canvas').offsetWidth;
    canvas.height = document.querySelector('canvas').offsetHeight;
    init();
  });

  function Circle(x, y, dx, dy, radius) {
    this.x = x;
    this.y = y;
    this.dx = dx;
    this.dy = dx;
    this.radius = radius;
    this.minRadius = radius;
    this.color = colorArray[Math.floor(Math.random() * colorArray.length)];

    this.draw = function() {
      if (this.radius < 0) {
        this.radius = this.minRadius;
      }
      c.beginPath();
      c.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
      c.fillStyle = this.color;
      c.fill();
    }

    this.update = function() {
      if (this.y + this.radius > innerHeight || this.y - this.radius <= 0) {
        this.dy = -this.dy;
      }
      if (this.x + this.radius > canvas.width|| this.x - this.radius <= 0) {
        this.dx = -this.dx;
      }
      this.x+=this.dx;
      this.y+=this.dy;

      if (mouse.x - this.x < 50 && mouse.x - this.x > -50 && mouse.y - this.y < 50 && mouse.y - this.y > -50) {
        if (this.radius < topRadius) {
          this.radius += 1; 
        }
      } else if (this.radius > this.minRadius){
        this.radius -= 1;
      }

      this.draw();
    }
  }

  let circleArray = [];
  function init() {
    circleArray = [];
    for (let i =0; i<50; i++) {
      let radius = Math.random() * 10;
      let x = Math.random() * (canvas.width - radius*2) + radius;
      let y = Math.random() * (canvas.height - radius * 2) + radius;
      let dx = (Math.random() - 0.5) * 4;
      let dy = (Math.random() - 0.5 )* 4;
      circleArray.push(new Circle(x, y, dx, dy, radius));
    }
  }

  function animate() {
    requestAnimationFrame(animate);
    c.clearRect(0,0, canvas.width, innerHeight);

    for(let i=0; i < circleArray.length; i++) {
      circleArray[i].update();
    }
  }
  init();
  animate();
}

$('#startstop').click(function() {
  if(!timeOut) {
    timeOut = setTimeout(circles, 1000);
  } else {
    clearTimeout(timeOut);
    timeOut = null;
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="display: flex; justify-content: space-around;">
  <canvas style="width: 100px; height: 800px; background: red;"></canvas>

<div id="startstop">toggle</div>
</div>

2 个答案:

答案 0 :(得分:1)

此动画未停止,因为您在Category | Sum of Transaction_Row A -1 C 1 上调用了clearTimeout,但只运行了一次。您的问题是setTimeout函数的进一步问题。这相对循环animate。您可以将其存储为请求,然后cancelAnimationFrame

答案 1 :(得分:1)

你非常接近解决方案;)

在函数animate中添加第3行(for循环之前),即具有此值:

if (!timeOut) return;

祝你好运!