javascript - 从左到右移动画布 - 从右到左,改变颜色和大小
问题描述
我必须创建一个从左到右,从右到左移动的矩形。
我想在矩形每通过 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);
感谢您提前回答!
解决方案
你需要做几件事。首先,您需要为每个有可能发生变化的事物创建变量。这包括size
盒子的,color
盒子dir
的,盒子的动作:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
x = 0,
size = 50,
dir = 1,
boxColor = "#ffffff",
last = performance.now();
变量dir
是1
,这意味着它将采用您盒子的当前方向并将其乘以1
。如果你想改变你的盒子的方向,我们需要减去x
。这意味着我们需要在每次盒子撞到右侧墙壁时更改为,并在盒子撞到左侧墙壁时将其更改dir
回。为此,我们可以添加一个名为的辅助函数,该函数检查框的宽度 + 其大小是否超过了画布的宽度。如果是,我们就知道盒子已经越过了画布容器的右侧。因此,我们可以将盒子的方向更改为-1
1
bounce
-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
在进行此检查之前进行四舍五入。此外,我们需要给这个检查留有一点余地,因为我们可能会跳过第20
th 个像素,因此永远不会得到 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>
推荐阅读
- c - 用 C 编写的反转共享库以使用 GDB 提取端口号
- javascript - 在对象内部拥有类
- github - 从一个帐户,多个电子邮件提交到 github
- html - 专注于较小屏幕上的一个区域的 SVG
- swift - 如何在 Firestore 中将数据添加到当前用户的 UID?(斯威夫特,iOS)
- r - 关于 R 中 ggplot 中的分组
- angular - 如何使用 fetch in angular 从 api 访问精确数组?
- r - R导入一些以相同字符串开头的xlsx文件,忽略同一文件夹中的其他文件
- angular - Firebase 身份验证单元测试通过带有 Angular 的模拟器
- iis - 即使标头存在,HSTS 仍显示已禁用