使用setInterval无限绘制矩形

时间:2014-12-09 03:37:16

标签: javascript canvas setinterval animated rect

我试图学习如何使用setInterval函数使用ONLY画布来学习基本动画。 我试图在屏幕上绘制一个简单的矩形,并每100毫秒将其移动到右边的1个像素。但是,当我这样做时,它会覆盖前一个矩形。我打电话给clearRect(),但似乎没有做任何事情。

如何让这个矩形平滑地穿过屏幕而不留下痕迹? 另外,如果有更好的方法来实现这一点而不是使用clearRect()和translate(),请分享。

var ctx = document.getElementById('mycanvas').getContext('2d');
var a = setInterval(draw,100);

var x = 50;
function draw()
{
    ctx.clearRect(0,0,300,300);
    ctx.translate(1,0);
    ctx.rect(x,50,50,50);
    ctx.stroke();
}

5 个答案:

答案 0 :(得分:0)

您的x变量永远不会改变,因此您的形状不会移动。你需要递增x才能获得移动:

var x = 50;
function draw(){
    ctx.clearRect(0,0,300,300);
    ctx.translate(1,0);
    ctx.rect(x,50,50,50);
    ctx.stroke();
    x++;
}

答案 1 :(得分:0)

为了获得一个平滑的动画,其中形状和其他精灵在屏幕上移动(甚至保持静止),最好制作一个clearScreen方法,它基本上以任何背景颜色绘制整个画布画布是。它基本上只是一个在整个画布上绘制白色(或任何你正在使用的背景颜色)矩形的函数。然后,调用绘制函数,它将生成所有必要的绘图。这样,就不会有任何过去或任何过去的动作,你不必在每个矩形上调用clearRect()

基本上,该功能将擦除画布,您可以重绘任何需要的内容,以使框的动画在屏幕上移动。

这有意义吗?

编辑: 另外,要清楚,您可以根据画布的大小和背景的颜色制作自己的clearScreen方法。它并不难,它只是在屏幕上画一个矩形。

答案 2 :(得分:0)

只需在每次通话时递增x

var canvas = document.getElementById('mycanvas')
var ctx = canvas.getContext('2d');
var a = setInterval(draw,100);

        var x = 50;
        function draw(){
            canvas.width = canvas.width; // clears the canvas
            ctx.rect(x++,50,50,50);
            ctx.stroke();
            if (x > 250) // resets the position
              x = 50;
        }
<canvas id="mycanvas"></canvas>

我也删除了那个翻译,因为没有必要只为方形动画做这个。

答案 3 :(得分:0)

您可以采用两种不同的方式:

您可以继续使用rect()stroke(),但需要事先致电beginPath()。当您调用rect()之类的方法时,会保留一个名为“路径”的列表,其中包含您创建的所有形状或“子路径”。然后,当您致电stroke()时,会绘制整个路径。因此,即使您清除屏幕,所有过去的矩形仍会在路径中被记住,然后再次绘制。 beginPath()清除该列表。

var x = 50;
function draw() {
    ctx.clearRect(0, 0, 300, 300);
    ctx.beginPath();
    ctx.rect(x, 50, 50, 50);
    ctx.stroke();
    x++;
}

或者,您可以将rect()stroke()合并为一行,而无需调用beginPath()。那是因为矩形既是同时创建和绘制的,也没有放在列表中。

var x = 50;
function draw() {
    ctx.clearRect(0, 0, 300, 300);
    ctx.strokeRect(x, 50, 50, 50);
    x++;
}

无论哪种方式,我建议递增x而不是使用translate(),因为translate()基本上会移动画布上绘制的虚构“笔”。因此,如果您translate(50, 50),然后尝试在画布上的(0,0)处绘制一个矩形,它实际上将位于(50,50)。

作为Microsoft puts it on MSDN,“翻译方法有效地重新映射画布上的(0,0)原点。”

如果您反复这样做,将很难跟踪您实际绘制的位置。

答案 4 :(得分:0)

尝试使用beginPath()和closePath():

&#13;
&#13;
var maxX, x = 0,
  s = 50,
  maxY;

var repaint = function(ctx) {
  if (x + s >= maxX) { //reached end of the canvas
    return;
  }
  ctx.clearRect(0, 0, maxX, maxY); //clear previous
  ctx.beginPath(); //start drawing
  ctx.rect(x, s, s, s);
  ctx.stroke();
  ctx.closePath(); //stop drawing
  x++;
  setTimeout(function() {
    repaint(ctx); //continue here
  }, 100);
};

var cnvs = document.getElementById('canvas');
maxX = cnvs.width;
maxY = cnvs.height;
repaint(cnvs.getContext('2d'));
&#13;
canvas {
  border: 1px solid grey;
}
&#13;
<canvas width="360" height="180" id='canvas'>HTML5 canvas not supported</canvas>
&#13;
&#13;
&#13;