每次循环迭代后Canvas都不会更新

时间:2014-05-20 01:58:42

标签: javascript html5 canvas html5-canvas

我做了一个小javascript牛顿分形图。我有两个循环迭代画布上的每个像素,但只有整个画布迭代后才会出现图像。是什么给了什么?

我的代码如下。虽然数学可能有点令人困惑,但是使用微积分,复数等等,我确信代码本身很容易遵循(虽然显然没有优化。)你可能想看的函数是cGraph。

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Newton Fractal Grapher</title>
</head>

<body>
    <canvas id="myCanvas" width="700" height="700" ></canvas>
<script type='text/javascript'>
var winWidth = document.getElementById("myCanvas").clientWidth;
var winHeight = document.getElementById("myCanvas").clientHeight
var ctx = document.getElementById("myCanvas").getContext("2d");

function cAdd(a,b) {return [a[0]+b[0],a[1]+b[1]];}

function cSubtract(a,b) {return [a[0]-b[0],a[1]-b[1]];}

function cMultiply(a,b) {return [a[0]*b[0]-a[1]*b[1],a[1]*b[0]+a[0]*b[1]];}

function cDivide(a,b) {return [ (a[0]*b[0]+a[1]*b[1])/(b[0]*b[0]+b[1]*b[1]) , (a[1]*b[0]-a[0]*b[1])/(b[0]*b[0]+b[1]*b[1]) ];}

function cExp(a,b) {
var x = a;
for (var i = 1; i < b; i++)
x = cMultiply(x,a);
return x;
}

var graphXmin = -1.1;
var graphXmax = 1.1;
var graphYmin = -1.1;
var graphYmax = 1.1;
var graphZmin = -1;
var graphZmax = 1;
var graphX;
var graphY;
var graphZ;

function cGraph(func)
{
    var z = [0,0];
    for (var x=0; x<winWidth; x++)
        for (var y=0; y<winHeight; y++)
        {
            graphX = (x/winWidth)*(graphXmax - graphXmin)+ graphXmin;
            graphY = (y/winHeight)*(graphYmax - graphYmin)+ graphYmin;
            graphZ = func([graphX,graphY]);
            z[0] = Math.round(    (graphZ[0]-graphZmin)/(graphZmax-graphZmin)*255    );
            z[1] = Math.round(    (graphZ[1]-graphZmin)/(graphZmax-graphZmin)*255    );
            ctx.fillStyle = "rgb("+z[0]+","+(255-[z[1]])+",0)";
            ctx.fillRect(x, winHeight-y, 1, 1);
        }
}

function cCube(x) {return cSubtract(  cExp(x,3)  ,[1,0])}

function cFive(x) {return cSubtract( cExp(x,5) , [1,0]) }

function cEight(x) {return   cSubtract(      cAdd( cExp(x,8)  , cMultiply(cExp(x,4) ,[0,4]) )     ,      [16,0] )}

function cDeriv(x,func) {
    return cDivide(
        cSubtract(
            func(  cAdd(x,[.0001,0])  ),
            func(  cSubtract(x,[.0001,0])  )
        ),
        [.0002,0]
    )
}

function cNewton(x,func)
{
    for (count = 0; count < 500; count++)
    {
        x = cSubtract( x,cDivide(func(x), cDeriv(x,func)));
        if (func(x)[0] < 0.001 && func(x)[0] > -0.001)
            return x;
    }
    return [255,255];
}

cGraph(   function(x){return cNewton(x,cFive)}   );

</script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

浏览器在重新绘制屏幕之前等待所有脚本完成运行。因此,在出现任何内容之前,您必须完成所有for循环。

所以你要做的是将for循环分解为setTimeoutsetIntervals,以便浏览器在每个循环之间重新绘制,你可以看到结果。

这个小提琴显示在行动中http://jsfiddle.net/Mw3WB/

一切都与图形函数保持相同的执行

function cGraph(func)
{
  var z = [0,0];
  var x = 0;

   var outer = setInterval(function(){
     if(x>= winWidth){
      clearInterval(outer);   
     }
     else{
       for (var y=0; y<winHeight; y++)
       {
        graphX = (x/winWidth)*(graphXmax - graphXmin)+ graphXmin;
        graphY = (y/winHeight)*(graphYmax - graphYmin)+ graphYmin;
        graphZ = func([graphX,graphY]);
        z[0] = Math.round(    (graphZ[0]-graphZmin)/(graphZmax-graphZmin)*255    );
        z[1] = Math.round(    (graphZ[1]-graphZmin)/(graphZmax-graphZmin)*255    );
        ctx.fillStyle = "rgb("+z[0]+","+(255-[z[1]])+",0)";
        ctx.fillRect(x, winHeight-y, 1, 1);
       }
       x++
    }
  },20);


}