[英]How to render HTML5 canvas within a loop
我正在做以下事情:
我正在運行一個for循環,每次我得到一個新的信息,並希望在畫布上繪制它。 問題是畫布是在循環結束后繪制的,我看不到沒有動畫。 如果我介入調試或使用警報消息,它將立即繪制到畫布。 我該怎么做?
這是我的代碼,你可以看到我已經嘗試過多種方式的setTimeout但是沒有用。
for(var i=0;i<1000; i ++)
{
addLines(ga.getBestCreature()); // This method draw on the canvas
setTimeout(function() {
ga.startEvolution(1); // This method change the best creature
}, 10);
}
淹死方法:
function addLines(best) {
if(!best) {
return;
}
var global_path = best.data;
redraw(); // Clear off the canvas
var cityA;
var cityB;
for (var i = 0; i < (global_path.length - 1); i++) {
cityA = ga.cities[global_path[i]];
cityB = ga.cities[global_path[i+1]];
ctx.moveTo(cityA.x,cityA.y);
ctx.lineTo(cityB.x,cityB.y);
ctx.stroke();
}
}
有任何想法嗎??
更新:在被建議使用requestAnimationFrame之后,我發布了類似的東西。 這是最好的approuch嗎? 我正在更新一個名為'run'的全局變量,點擊事件
var run = 0;
function animate() {
if(run > 0) {
ga.startEvolution(1);
run--;
}
addLines(ga.getBestCreature());
requestAnimationFrame(animate);
}
animate();
您可以查看requestAnimationFrame
: https : //developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
而我們這樣的事情:
function loop() {
addLines(ga.getBestCreature());
// execute loop function over and over
requestAnimationFrame(loop);
}
最好的方法是分開關注點:讓動畫循環持續運行,並且“每次[你]獲得新信息”,更新你的場景描述,它會在顯示准備就緒后立即繪制。
所以第一個非常簡單的演示:這里的'新信息'是用戶點擊。
var cv = document.getElementById('cv'); var ctx = cv.getContext('2d'); var cvWidth = cv.width; var cvHeight = cv.height; // Simple scene description : an array of colored rects var everyObject = [ [60, 70, 30, 30, 'yellow'] ]; // animation : always running loop. function animate() { // call again next time we can draw requestAnimationFrame(animate); // clear canvas ctx.clearRect(0, 0, cvWidth, cvHeight); // draw everything everyObject.forEach(function(o) { ctx.fillStyle = o[4]; ctx.fillRect(o[0], o[1], o[2], o[3]); }); // ctx.fillStyle = '#000'; ctx.fillText('click to add random rects', 10, 10); } animate(); // click handler to add random rects window.addEventListener('click', function() { addRandRect(); }); function addRandRect() { var randColor = Math.random() > 0.5 ? 'blue' : 'red'; everyObject.push([Math.random() * cvWidth, Math.random() * cvHeight, 10 + Math.random() * 40, 10 + Math.random() * 40, randColor]); }
<canvas id='cv' width=400 height=200></canvas>
現在,如果你想要某種動畫,或者使用setTimeOut的簡單版本是:
var cv = document.getElementById('cv'); var ctx = cv.getContext('2d'); var cvWidth = cv.width; var cvHeight = cv.height; // Simple scene description : an array of colored rects var everyObject = [ [60, 70, 30, 30, 'yellow'] ]; // animation : always running loop. function animate() { // call again next time we can draw requestAnimationFrame(animate); // clear canvas ctx.clearRect(0, 0, cvWidth, cvHeight); // draw everything everyObject.forEach(function(o) { ctx.fillStyle = o[4]; ctx.fillRect(o[0], o[1], o[2], o[3]); }); // ctx.fillStyle = '#000'; ctx.fillText('click to add 4 random rects with a delay', 10, 10); } animate(); // click handler to add random rects window.addEventListener('click', function() { addRandRect(); setTimeout(addRandRect, 300); setTimeout(addRandRect, 600); setTimeout(addRandRect, 900); }); function addRandRect() { var randColor = Math.random() > 0.5 ? 'blue' : 'red'; everyObject.push([Math.random() * cvWidth, Math.random() * cvHeight, 10 + Math.random() * 40, 10 + Math.random() * 40, randColor]); }
<canvas id='cv' width=400 height=200></canvas>
(順便說一下,如果感興趣,我在這里寫了關於動畫的文章: http : //codepen.io/gamealchemist/post/animationcanvas1 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.