首页 > 解决方案 > 从左到右移动画布 - 从右到左,改变颜色和大小

问题描述

我必须创建一个从左到右,从右到左移动的矩形。

我想在矩形每通过 20 个像素后更改矩形的颜色(随机颜色)。当矩形在右边时,它的大小会变成100px,当它在左边时,它的大小会变回50px

现在我有:

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    x = 0,
    last = performance.now();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
function draw(timestamp) {
  requestAnimationFrame(draw);

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.rect(x, 50, 50, 50);
  ctx.fillStyle = "#ffffff";
  ctx.fill();

  x += (timestamp - last) / 10;
  last = timestamp;
}
requestAnimationFrame(draw);

感谢您提前回答!

标签: javascriptcanvashtml5-canvas

解决方案


你需要做几件事。首先,您需要为每个有可能发生变化的事物创建变量。这包括size盒子的,color盒子dir的,盒子的动作:

var canvas = document.getElementById('canvas'),
  ctx = canvas.getContext('2d'),
  x = 0,
  size = 50,
  dir = 1,
  boxColor = "#ffffff",
  last = performance.now();

变量dir1,这意味着它将采用您盒子的当前方向并将其乘以1。如果你想改变你的盒子的方向,我们需要减去x。这意味着我们需要在每次盒子撞到右侧墙壁时更改为,并在盒子撞到左侧墙壁时将其更改dir回。为此,我们可以添加一个名为的辅助函数,该函数检查框的宽度 + 其大小是否超过了画布的宽度。如果是,我们就知道盒子已经越过了画布容器的右侧。因此,我们可以将盒子的方向更改为-11bounce-1. 我们还可以将盒子的位置重新定位到墙外,以防它在移动时设法夹在墙上。我们可以应用相同的逻辑来检查框是否超过了画布的左边缘。在此检查期间,我们还可以更改size我们的盒子的大小,使其在碰到右壁时增长,并在碰到左壁时收缩:

function bounce() {
    if(x+size > canvas.width) { // if right edge passes the widtth of the canvas, change the dir
    dir *= -1;
    size = 100;;
    x = canvas.width-size; // move the box outside of the wall (boundary)
  } else if(x < 0) {
    dir *= -1;
    size = 50;
    x = 0;
  }
}

因此,我们还必须将x方程的变化更改为:

x += dir*(timestamp - last) / 10;

最后,我们需要添加一种方法来改变盒子的颜色。这可以通过取位置的模 ( %)来完成x。如果x % 20等于0,我们知道我们的盒子在一个x是 的倍数的位置上20,所以我们改变它的颜色。但是,由于x位置不会1每次都改变 ',因此我们需要x在进行此检查之前进行四舍五入。此外,我们需要给这个检查留有一点余地,因为我们可能会跳过第20th 个像素,因此永远不会得到 20 的倍数,所以我们可以将<=1其用作检查。(注意:这不是完美的检查,但这是我现在能想到的最好的检查:/):

function color() {
    if(Math.round(x) % 20 <= 1 ) { // if the x divide 20 gives a remainder of 0
    var r = Math.floor(Math.random() * 255);
    var g = Math.floor(Math.random() * 255);
    var b = Math.floor(Math.random() * 255);
    boxColor = "rgb(" +r +", " +g +", " +b +")";
  } else {
    console.log(Math.round(Math.abs(x)) % 20);
  }
}

请参见下面的示例:

var canvas = document.getElementById('canvas'),
  ctx = canvas.getContext('2d'),
  x = 0,
  size = 50,
  dir = 1,
  boxColor = "#ffffff",
  last = performance.now();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function draw(timestamp) {
  bounce();
  color();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.fillStyle = boxColor;
  ctx.rect(x, canvas.height / 2 - size / 2, size, size);
  ctx.fill();

  x += dir * (timestamp - last) / 10;
  last = timestamp;
  requestAnimationFrame(draw);
}

function bounce() {
  if (x + size > canvas.width) { // if right edge passes the widtth of the canvas, change the dir
    dir *= -1;
    size = 100;
    x = canvas.width - size; // move the box outside of the wall (boundary)
  } else if (x < 0) {
    dir *= -1;
    size = 50;
    x = 0;
  }
}

function color() {
  if (Math.round(x) % 20 <= 1) { // if the x divide 20 gives a remainder of 0
    var r = Math.floor(Math.random() * 255);
    var g = Math.floor(Math.random() * 255);
    var b = Math.floor(Math.random() * 255);
    boxColor = "rgb(" + r + ", " + g + ", " + b + ")";
  }
}

requestAnimationFrame(draw);
body {
  margin: 0;
}
<canvas id="canvas" style="border: 1px solid black; background-color: black;"></canvas>


推荐阅读