我刚开始学习javascript。 我的问题是,网站在几秒钟后放慢了速度。我正在使用setinterval来“勾选”屏幕上的内容,我觉得这可能是导致问题的原因。
这是我的代码:
var r = [];
var ctx;
function init() {
ctx = document.getElementById("canvas").getContext("2d");
for(var i = 0; i < 20; i++) {
var x = Math.floor(Math.random() * (ctx.canvas.width - 20)) + 10;
var y = Math.floor(Math.random() * (ctx.canvas.height - 20)) + 10;
r.push(new Rect(x,y, 10, 10, ctx));
}
window.setInterval(tick,10);
window.setInterval(draw,10);
}
function tick() {
for(var i = 0; i < r.length; i++) {
r[i].tick();
}
}
function draw() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
for(var i = 0; i < r.length; i++) {
r[i].draw();
}
ctx.lineWidth = 5;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.stroke();
}
这是另一个课程:
class Rect {
constructor(x, y, width, height, ctx) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.cxt = ctx;
this.xVel = 2.5;
this.yVel = 2.5;
if (Math.random() < 0.5) {
this.xVel = -this.xVel;
}
if (Math.random() < 0.5) {
this.yVel = -this.yVel;
}
}
tick(){
this.x += this.xVel;
this.y += this.yVel;
if (this.x + this.width >= ctx.canvas.width | this.x <= 0){
this.xVel = -this.xVel;
}
if (this.y + this.height >= ctx.canvas.height | this.y <= 0){
this.yVel = -this.yVel;
}
}
draw() {
ctx.fillRect(this.x,this.y,this.width,this.height);
}
}
那究竟是什么原因导致这个问题以及如何解决?
您可以在此处下载文件:https://drive.google.com/file/d/1pg4ASPvjbo2ua_7cCvQvzucLgbegtiw6/view?usp=sharing
答案 0 :(得分:4)
此问题出在您的绘图功能中。
Canvas-es记住绘制的所有线条,随着时间的推移它会减慢你的动画效果。
解决方案是通过调用ctx.beginPath()
来重置绘制列表的行function draw() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
for (var i = 0; i < r.length; i++) {
r[i].draw();
}
ctx.beginPath()
ctx.lineWidth = 5;
ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.stroke();
}
答案 1 :(得分:0)
首先,屏幕仅以16毫秒的速率刷新(假设每秒60帧)。所以在10毫秒内调用这两个函数有点矫枉过正。但是在现代浏览器中,我们现在有一个本机支持,可以在屏幕刷新时执行任何操作。它的请求动画帧叫做requestAnimationFrame(animationrDrawCallback)。
您可以在此处详细了解:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame。现在回到你的代码,它可以像这样重构:
const r = [];
const ctx;
function init() {
ctx = document.getElementById("canvas").getContext("2d");
for(let i = 0; i < 20; i++) {
const x = Math.floor(Math.random() * (ctx.canvas.width - 20)) + 10;
const y = Math.floor(Math.random() * (ctx.canvas.height - 20)) + 10;
r.push(new Rect(x,y, 10, 10, ctx));
}
// start our animation
window.requestAnimationFrame(render);
}
function render() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
r.forEach((item) => {
item.trick();
item.draw();
})
ctx.beginPath();
ctx.lineWidth = 5;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.stroke();
// this will be called at next screen refresh
window.requestAnimationFrame(render);
}
使用requestAnimationFrame的 BIGGEST BONUS 是当标签不再处于焦点时它将停止执行。智能手机的巨大推动力。希望这会有所帮助。