2016-05-27 11 views
0

内HTML5のキャンバスを描画する方法:私は、forループを通過することだし、毎回私は新しい情報を入手し、キャンバスに描きたい私は次の操作を行うためにtrtingだループ

。 問題は、ループが終了した直後にキャンバスが描画されているため、アニメーションが表示されないことです。 デバッグや警告メッセージを表示すると、immediatlyでキャンバスに描画されます。どうしたらいいですか?

ここに私のコードがありますが、私は既に複数の方法で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を使用するように勧められた後、私はこのようなものを出しました。これは最善のことですか? 私はあなたが​​を見て取ることができるクリックイベント

var run = 0; 
function animate() { 

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

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

animate(); 

答えて

1

:このような何かをhttps://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

と米国のそれアニメーションループを連続して実行し、「新しい情報が得られるたびに」シーン記述を更新すると、表示が準備されるとすぐに描画されます。

最初の非常に簡単なデモ:ここでは「新しい情報」はユーザーのクリックです。

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

それはうまくいったが、私はそれを修正しなければならなかった。今はこれがベストプラクティスだとは思わない。私はforループで気付いた、requestAnimationFrameは起動せず、ループが終了するのを待ちます。だから私は基本的に私のロジックをanimate()メソッドに追加しています。あなたは私の質問の終わりに私をチェックすることができます、私はそこにそれを追加しました – Hasholef

1

上の 'RUN' と呼ばれるグローバル変数を更新しています:あなたの

function loop() { 
    addLines(ga.getBestCreature()); 

    // execute loop function over and over 
    requestAnimationFrame(loop); 
} 
関連する問題