简体   繁体   English

如何在循环中呈现HTML5画布

[英]How to render HTML5 canvas within a loop

I'm trting to do the following: 我正在做以下事情:

I'm running through a for loop and each time I get a new information and want to draw it on the canvas. 我正在运行一个for循环,每次我得到一个新的信息,并希望在画布上绘制它。 The problem is that the canvas is being drawn just after the loop finish, and I can't see no animation. 问题是画布是在循环结束后绘制的,我看不到没有动画。 If I step in with debug, or with alert messages, it will draw to the canvas immediatly. 如果我介入调试或使用警报消息,它将立即绘制到画布。 How can I do it? 我该怎么做?

Here is my code, as you can see I've already tried with setTimeout in multiple ways but didn't worked. 这是我的代码,你可以看到我已经尝试过多种方式的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);   
    }

The drowing method: 淹死方法:

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();
    }
}

Any Ideas?? 有任何想法吗??

Update: After was advised to use the requestAnimationFrame, I've came out with something like this. 更新:在被建议使用requestAnimationFrame之后,我发布了类似的东西。 Is this the best approuch? 这是最好的approuch吗? I'm updating a global variable called 'run' on click events 我正在更新一个名为'run'的全局变量,点击事件

var run = 0;
function animate() {

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

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

animate();

You could take a look at requestAnimationFrame : https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame 您可以查看requestAnimationFramehttps//developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

And us it something like this: 而我们这样的事情:

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

    // execute loop function over and over
    requestAnimationFrame(loop);
}

Your best take is to separate concerns : have an animation loop continuously running, and, "each time [you] get a new information", update your scene description, it will draw as soon as the display is ready. 最好的方法是分开关注点:让动画循环持续运行,并且“每次[你]获得新信息”,更新你的场景描述,它会在显示准备就绪后立即绘制。

So a first very simple demo : here the 'new information' is a user click. 所以第一个非常简单的演示:这里的'新信息'是用户点击。

 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> 

Now if you want some kind of animation, or a simple version using setTimeOut would be : 现在,如果你想要某种动画,或者使用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> 

(By the way i wrote about animation here if interested : http://codepen.io/gamealchemist/post/animationcanvas1 ) (顺便说一下,如果感兴趣,我在这里写了关于动画的文章: http//codepen.io/gamealchemist/post/animationcanvas1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM