为什么context.clearRect()不在requestAnimationFrame循环中工作?

时间:2016-09-11 20:37:05

标签: javascript canvas

我在页面上有一个画布元素,其上绘制了一个圆圈并在其上移动。在循环的每次迭代中,圆圈被移动一个像素。这是代码。



  function clearPage() {
    context.clearRect(0,0,300, 150);
  };

  var canvasEl = document.getElementById("main");
  var context = canvasEl.getContext('2d');
  
  context.fillStyle = 'red';
  context.strokeStyle = 'red';
 
  var x = 0;
  function moveCircle() {
    clearPage();
    context.arc(x, 75, 20, 0, 2* Math.PI);
    context.stroke();
    x++;
    window.requestAnimationFrame(moveCircle);
  }
  moveCircle();

canvas {
  border: 1px solid black;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
  <head>
    <title>Canvas Practice</title>
  </head>
  <body>
    <canvas id='main'></canvas>
    <script src="main.js"></script>
  </body>
</html>
&#13;
&#13;
&#13;

很明显,我的函数会在绘制新圆之前清除页面。虽然在运行时,您可以看到它在页面上留下先前绘制的圆圈。如果你在完成动画制作后调用clearPage()函数,整个页面就会像预期的那样被清除。

最重要的是,我只是想知道为什么会这样。它似乎并不完全直观,但我最好的猜测是它与requestAnimationFrame()的行为有关;

1 个答案:

答案 0 :(得分:1)

在绘制圆弧之前,您应该使用context.beginPath();

原因是弧被添加到同一路径,因此每个命令都会重绘整个路径(请参阅https://www.w3.org/TR/2dcontext/#dom-context-2d-arc)。使用beginPath为每个弧启动一个新路径,因此不会重绘以前的路径。

function clearPage() {
    context.clearRect(0,0,300, 150);
  };

  var canvasEl = document.getElementById("main");
  var context = canvasEl.getContext('2d');
  
  context.fillStyle = 'red';
  context.strokeStyle = 'red';
 
  var x = 0;
  function moveCircle() {
    clearPage();
    context.beginPath();
    context.arc(x, 75, 20, 0, 2* Math.PI);
    context.stroke();
    x++;
    window.requestAnimationFrame(moveCircle);
  }
  moveCircle();
canvas {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
  <head>
    <title>Canvas Practice</title>
  </head>
  <body>
    <canvas id='main'></canvas>
    <script src="main.js"></script>
  </body>
</html>