画布从左下方一直到右上方不断变黑

时间:2019-02-08 09:21:51

标签: javascript html5-canvas

在此页面https://spiritshare.org/circles.html上,我正在使用一些简单的代码来渲染一些在重力网格上移动的圆。网格沿圆形移动时的颜色给网格留下深刻的印象,然后在屏幕上绘制权重。但是某些东西正在吞噬整个宇宙,并将其像大爆炸一样倒塌到左上角!

我认为这可能是垃圾收集器,或者可能是代码中的某个数学错误? (所有数学运算都在第一页的底部)。这是相关的部分,其中颜色与圆圈混合在一起。

p = (y * fullW + x) * 3;
d = Math.sqrt(xd + yd);// * 0.5; //Math.sqrt( xd + yd );
// console.log(p);
//console.log( c.r, c.g, c.b );

if( cfg.safe_colors == true ) {
    if( typeof cfg.max_color == 'undefined' ) cfg.max_color = 255;
    gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r) & cfg.max_color;
    gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g) & cfg.max_color;
    gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b) & cfg.max_color;
} else if( typeof cfg.max_color != 'undefined' ) {
    gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r);
    gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g);
    gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b);
    if( gravity[p] > cfg.max_color ) gravity[p] = cfg.max_color;
    if( gravity[p+1] > cfg.max_color ) gravity[p+1] = cfg.max_color;
    if( gravity[p+2] > cfg.max_color ) gravity[p+2] = cfg.max_color;
} else {
    gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r);
    gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g);
    gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b);
}

一切似乎都可以正常工作,但是过了一会儿,也许当一些碎片开始堆积或者某个漏洞有机会散布在某个地方时,屏幕很快就会开始逐个堆积黑色像素。

不应该这样做...我已经对其进行了更新,因为它在更严格的CPU控制下执行的次数较少,但是当颜色变得过于浓密和模糊时仍会出现毛刺(按住B键以增加模糊,警告会消耗过多的CPU资源。

1 个答案:

答案 0 :(得分:0)

通常,提高代码效率可以解决该问题,该问题在示例中不再存在,因此,由于我将发布分析,因此我将关闭它,随时删除或不删除它。

我认为最有可能的canvasrenderendertext.putImageData是一个线程化操作,当脚本的主要处理使用了太多的CPU时,该操作会耗尽时间来完成源图像的复制。

为解决此问题,我添加了以下处理程序以在处理重力网格时调整计时器间隔。

var gravTimeout;
function animate() {
    if( !cfg.setup ) return;
    var tn = new Date();
    gravitate();
    var tx = new Date();
    var td = tx - tn;
    var chg=false;
    if( gravTimeout < td ) { // using too much cpu.
        gravTimeout *= 1.5;
        chg=true;
    } else if( gravTimeout > td*2/3 ) { // going too slowly.
        gravTimeout /= 1.5;
        chg=true;
    }
    if(chg){
        clearInterval(gravTimer);
        gravTimer = setInterval( "animate()", gravTimeout );
        if( gravTimeout > 600 )
            console.log("gt="+gravTimeout);
    }
    //console.log(td, tn.getSeconds(), tx.getSeconds());
}