使用setTimeout从循环内部重新绘制html画布的推荐方法
Recommended way to redraw an html canvas from inside a loop using setTimeout
我研究了很多,主要是在SO中,关于setTimeout
"不阻塞",因此不适合在for循环中使用,因为循环不断进行,而函数调用不断增加。
我有一个记录图像处理算法的HTML文件,所以我想以"人类可读"的速度显示活动像素"行走"。我尝试过的实现没有工作,如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body onload="run();">
<canvas id="Canvas" width=501 height=601></canvas>
<script>
function run() {
reevaluate();
};
var fixedcenteri;
var fixedcenterj;
function reevaluate() {
var altura_imagem = 50;
var largura_imagem = 40;
for (var i = 0; i < altura_imagem; i++) {
for (var j = 0; j < largura_imagem; j++) {
fixedcenteri = i;
fixedcenterj = j;
setTimeout(draw, 100);
// if I uncomment this I can see what I want, but...
// alert(i+j);
};
};
};
function draw () {
var elem = document.getElementById('Canvas');
var cx = elem.getContext('2d');
w = elem.width;
h = elem.height;
cx.fillStyle = "white";
cx.fillRect(0,0,w,h);
cx.fillStyle = 'blue';
cx.fillRect(fixedcenteri, fixedcenterj, 10, 10);
}
</script>
</body>
</html>
尝试RequestAnimationFrame!
RequestAnimationFrame是异步的,就像setTimeout一样,它比setTimeout更有效。
此外,它还提供动画分组和屏幕外动画的自动停止。
你甚至可以使用以下技术将其限制到你想要的FPS:
var fps = 15;
function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
// your draw() stuff goes here
}, 1000 / fps);
}
最简单的实现是将所有绘制命令存储在一个数组中,然后使用setTimeout
处理该数组,在绘制命令之间等待。
这里有一个简单的例子-> http://jsfiddle.net/K4D84/
//in your initial loop instead of draw
drawCommands.push({i: i, j: j});
然后……
function slowDraw(index) {
index = index || 0;
var drawCommand = drawCommands[index];
if (drawCommand) {
fixedcenteri = drawCommand.i;
fixedcenterj = drawCommand.j;
setTimeout(function () {
draw();
slowDraw(++index);
}, 100);
}
}
我想这就是你想要的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body onload="draw();">
<canvas id="Canvas" width=501 height=601></canvas>
<script>
var fixedcenteri = 0;
var fixedcenterj = 0;
function draw () {
var elem = document.getElementById('Canvas');
var cx = elem.getContext('2d');
w = elem.width;
h = elem.height;
cx.fillStyle = "white";
cx.fillRect(0,0,w,h);
cx.fillStyle = 'blue';
cx.fillRect(fixedcenteri, fixedcenterj, 10, 10);
if(fixedcenteri < 50) {
if(fixedcenterj < 40) {
fixedcenterj++;
} else {
fixedcenterj = 0;
fixedcenteri++;
}
setTimeout(draw, 100);
}
}
</script>
相关文章:
- 有没有一种方法可以仅使用HTML/CSS来隐藏基于特定值的数据单元格
- 用HTML在不同屏幕上显示和隐藏内容的方法
- 使用jquery.load('pageName')方法时,未从应用程序缓存加载Html页
- 有没有一种方法可以在没有文档或jQuery的情况下使用javascript解码html实体
- 在HTML/JavaScript中,有没有一种方法可以在图像开始加载时知道图像的最终布局尺寸
- 有更好的方法吗?(递归解析HTML unicode实体)
- 如何在JQuery中的.html()方法中包含fadeneffect
- jQuery.html()方法语法
- 将jquery HTML方法中的数据检索到数组中
- HTML方法未使用Document Ready加载值
- 我不明白jQuery .each()和.html()方法是如何工作的
- 使用HTML方法的CSS属性
- Jquery从HTML方法中排除元素
- 如何从$(..).html()方法给出的多行字符串中删除缩进
- jQuery .html方法在表单提交后返回破碎的代码
- 在jQuery中使用html()方法和一个符号
- 如何在. HTML()方法中组合HTML标记和变量?
- jQuery不要在.HTML()方法中解析转义的HTML
- Jquery html()方法获取<超文本标记语言
- Jquery& #39;s html()方法不能有效插入html代码