如何使用for循环在画布中移动矩形位置

时间:2017-03-04 13:18:23

标签: javascript css html5 canvas

首先,我是画布的新手,我一直试图绕过这两天,所以我真的很感激任何帮助。我的目标是让绿色矩形一次向上动画1个像素(这个数量现在并不重要)但我最终也想对红色矩形做同样的事情。如果我注释出for循环,你可以在我想要的起始位置看到矩形,但是当我在画布中添加for循环时是空白的,理论上我希望绿色矩形向上移动。 (或向下,实际上并不重要)。

$(document).ready(function() {
  var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    cw = canvas.width,
    ch = canvas.height;


  function rectangles() {

    var y = 0;
    // Starting point rectangles
    ctx.save();
    ctx.clearRect(0, 0, cw, ch);
    ctx.beginPath();
    ctx.fillStyle = "#006847";
    ctx.fillRect(0, 0, 200, 450);
    ctx.closePath();

    ctx.beginPath();
    ctx.fillStyle = "#CE1126";
    ctx.fillRect(400, 0, 200, 450);
    ctx.closePath();

    ctx.save();
    /*for (i = 0; i < 450; i++) {
        y = y + 1;
        ctx.beginPath();
        ctx.fillRect(0, y, 200, 450);
        ctx.closePath();
        ctx.clearRect(0, 0, cw, ch);
    }*/
  }

  setInterval(rectangles, 2000);
});
CSS : #canvas {
  border: 3px #000 solid;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="canvas-container">
  <canvas id="canvas" height="450" width="600"></canvas>
</div>

4 个答案:

答案 0 :(得分:3)

不需要for循环。您只需使用if语句即可完成此操作。

&#13;
&#13;
$(document).ready(function() {
    var canvas = document.getElementById("canvas"),
        ctx = canvas.getContext("2d"),
        cw = canvas.width,
        ch = canvas.height,
        GY = 0,
        RY = 0;

    rectangles();

    function rectangles() {
        if (GY > -450 && RY > -450) {
            GY -= 1;  // pixel
            RY -= 1;
        } else if (GY == -450 && RY == -450) {
            GY = 450;
            RY = 450;
        }
        // Starting point rectangles
        ctx.clearRect(0, 0, cw, ch);
        // green
        ctx.fillStyle = "#006847";
        ctx.fillRect(0, GY, 200, 450);
        // red
        ctx.fillStyle = "#CE1126";
        ctx.fillRect(400, RY, 200, 450);
        requestAnimationFrame(rectangles);
    }
});
&#13;
#canvas {
  border: 3px #000 solid;
  margin: 0 auto;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-container">
    <canvas id="canvas" height="450" width="600"></canvas>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

简短的回答是:你做不到。

原因是:在脚本执行完毕之前,您的浏览器不会呈现任何内容(因为只有浏览器才会返回其渲染上下文)。

使用requestAnimationFramehttps://developer.mozilla.org/de/docs/Web/API/window/requestAnimationFrame

$(document).ready(function() {
  var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    cw = canvas.width,
    ch = canvas.height;

  var y = 0;

  function rectangles() {

    // Starting point rectangles
    ctx.save();
    ctx.clearRect(0, 0, cw, ch);
    ctx.beginPath();
    ctx.fillStyle = "#006847";
    ctx.fillRect(0, 0, 200, 450);
    ctx.closePath();

    ctx.beginPath();
    ctx.fillStyle = "#CE1126";
    ctx.fillRect(400, 0, 200, 450);
    ctx.closePath();

    ctx.save();
    y++;

    ctx.beginPath();
    ctx.fillRect(0, y, 200, 450);
    ctx.closePath();
    ctx.clearRect(0, 0, cw, ch);
    if (y < 450)
      requestAnimationFrame( rectangles );
  }


  setInterval(rectangles, 2000);
});

答案 2 :(得分:0)

编辑:在此之后,暹罗做了一个更好的答案:HERE

画布变为空白,因为在函数rectangles()中,for循环计算位置并在闪烁时绘制矩形,在我们看到任何动画之前向我们显示最终状态(空白)。

所以我们在每次绘制新矩形之间都要花些时间。我还添加了一个索引i来记录已经过了多少时间,以计算矩形的新位置。请检查代码段和评论,看看是否需要。

&#13;
&#13;
$(document).ready(function() {
    var canvas = document.getElementById("canvas"),
        ctx = canvas.getContext("2d"),
        cw = canvas.width,
        ch = canvas.height;
        step = 1; // Distance the rectangle move each time
        refresh = 10; // Repaint interval
        var i = 0; // Record how far has the rectangle go

    function rectangles() {
        // Starting point rectangles
        ctx.save();
        ctx.clearRect(0, 0, cw, ch);
        ctx.beginPath();
        ctx.fillStyle = "#006847";
        // Leave blank area with height: i*step
        ctx.fillRect(0, 0, 100, ch-i*step); 
        ctx.closePath();

        ctx.beginPath();
        ctx.fillStyle = "#CE1126";
        ctx.fillRect(200, 0, 100, ch-i*step);
        ctx.closePath();

        ctx.save();
        i ++;
        // The canvas is blank, stop drawing
        if (ch-i*step < 0) {
          clearInterval(interval)
        }
    }
  interval = setInterval(rectangles, refresh);
  });
&#13;
#canvas {
    border: 3px #000 solid;
    margin: 0 auto;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="canvas-container">
  <canvas id="canvas" height="225" width="300"></canvas>
</div> 
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您无法实现的原因是因为画布是单个实体。在清除画布之前,不能移动矩形。 clearRect在这里进行救援。

我在名为clearCanvas的函数上创建了。在重新定位矩形之前,它将运行并清除画布。因此,您将使用新计算的位置每两秒重新绘制一次画布。

$(document).ready(function() {
  var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    cw = canvas.width,
    ch = canvas.height;

  var x = 100;
  var y = 100;

  function rectangles() {
    clearCanvas();
    var y = 0;
    // Starting point rectangles
    ctx.save();
    ctx.clearRect(0, 0, cw, ch);
    ctx.beginPath();
    ctx.fillStyle = "#006847";
    ctx.fillRect(x, 0, 50, 50);
    ctx.closePath();

    ctx.beginPath();
    ctx.fillStyle = "#CE1126";
    ctx.fillRect(x + 400, 0, 50, 50);
    ctx.closePath();

    ctx.save();


    if (x < 10) {
      x = 100;
    }
    x = x - 10;

  }

  setInterval(rectangles, 400);

  function clearCanvas() {
    ctx.clearRect(0, 0, cw, ch);
  }

});
#canvas {
  border: 3px #000 solid;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="canvas-container">
  <canvas id="canvas" height="450" width="600"></canvas>
</div>