2016-05-27 30 views
0

我trting做以下內HTML5畫布:如何呈現環

我通過一個運行循環,每次我得到一個新的信息,並希望把它畫在畫布上。 問題在於畫布剛剛在循環完成後繪製,而我看不到任何動畫。 如果我介入調試或警報消息,它將立即畫到畫布上。我該怎麼做?

這是我的代碼,你可以看到我已經用多種方式嘗試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); 
    } 

的drowing方法:

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嗎? 我更新了一個名爲「跑」上單擊事件

var run = 0; 
function animate() { 

    if(run > 0) { 
     ga.startEvolution(1); 
     run--; 
    } 

addLines(ga.getBestCreature()); 
    requestAnimationFrame(animate); 
} 

animate(); 

回答

1

你最好的辦法是分開關注點:讓動畫循環持續運行,並且,「每次[你]獲得新信息」,更新場景描述,只要顯示準備就緒,它就會畫出。

因此,第一個非常簡單的演示:這裏'新信息'是用戶點擊。

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

+0

好的工作,但我不得不修改它,現在我不認爲這是最好的做法。我發現wihtin for循環,requestAnimationFrame不會觸發,並會等待循環結束。所以我所做的基本上是將我的邏輯添加到animate()方法中。您可以在我的問題結尾處查看我的情況,我已將它添加到那裏 – Hasholef