将ImageData循环

putImageData on a loop

我正在尝试构建漂亮的图形图像(动画!),为屏幕上的每个像素计算颜色,然后同时显示所有像素。所以,我在循环中使用了 putImageData 函数。

但由于某种原因它不起作用。屏幕上只能看到最后一次迭代(1-2 秒后)。

我尝试在每次迭代后使用 FillRect,但没有帮助。

<html>
<head>
    <title>Full Screen Canvas Test</title>
    <style>
        html, body {
            overflow: hidden;
            margin: 0;
        }
    </style>
</head>
<body>

    <canvas id="mainCanvas"></canvas>

    <script>
        (function () {
            canvas = document.getElementById('mainCanvas');
            ctx = canvas.getContext("2d");              
            canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
            canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
            step = 1;

            function doit() {   
                rx = Math.floor(Math.random()*canvas.width);
                ry = Math.floor(Math.random()*canvas.height);
                gx = Math.floor(Math.random()*canvas.width);
                gy = Math.floor(Math.random()*canvas.height);
                bx = Math.floor(Math.random()*canvas.width);
                by = Math.floor(Math.random()*canvas.height);                                               

                var canvasData = ctx.createImageData(canvas.width, canvas.height);

                for (var i = 0; i < canvas.width; i+=step) {
                    for (var j = 0; j < canvas.height; j+=step) {
                        po = 2;
                        rd = Math.floor(Math.sqrt(Math.pow(rx - i, po)+Math.pow(ry - j, po)));
                        gd = Math.floor(Math.sqrt(Math.pow(gx - i, po)+Math.pow(gy - j, po)));
                        bd = Math.floor(Math.sqrt(Math.pow(bx - i, po)+Math.pow(by - j, po)));
                        maxd = 1400;
                        r = Math.floor((1 - rd/maxd)*255);
                        g = Math.floor((1 - gd/maxd)*255);
                        b = Math.floor((1 - bd/maxd)*255);

                        var index = (i + j * canvas.width) * 4;

                        canvasData.data[index + 0] = r;
                        canvasData.data[index + 1] = g;
                        canvasData.data[index + 2] = b;
                        canvasData.data[index + 3] = 255;


                    }
                }

                ctx.putImageData(canvasData, 0, 0);

            }       

            doit();
            doit();
            doit();
            doit();
            doit();
            doit();
            doit();
            doit();
        })();
    </script>
</body>

您需要使用 setInveral() 多次调用 doit() 函数,每次调用之间有时间延迟。您当前方法的问题在于,它是 运行 所有 doit() 一次迭代的结果,然后仅显示最后一个,因为它会覆盖您以前的结果。因此,您需要按顺序显示每个结果。

请参阅下面的工作示例:

<html>

<head>
  <title>Full Screen Canvas Test</title>
  <style>
    html,
    body {
      overflow: hidden;
      margin: 0;
    }
  </style>
</head>

<body>

  <canvas id="mainCanvas"></canvas>

  <script>
    (function() {
      canvas = document.getElementById('mainCanvas');
      ctx = canvas.getContext("2d");
      canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
      canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
      step = 1;

      function doit() {
        rx = Math.floor(Math.random() * canvas.width);
        ry = Math.floor(Math.random() * canvas.height);
        gx = Math.floor(Math.random() * canvas.width);
        gy = Math.floor(Math.random() * canvas.height);
        bx = Math.floor(Math.random() * canvas.width);
        by = Math.floor(Math.random() * canvas.height);

        var canvasData = ctx.createImageData(canvas.width, canvas.height);

        for (var i = 0; i < canvas.width; i += step) {
          for (var j = 0; j < canvas.height; j += step) {
            po = 2;
            rd = Math.floor(Math.sqrt(Math.pow(rx - i, po) + Math.pow(ry - j, po)));
            gd = Math.floor(Math.sqrt(Math.pow(gx - i, po) + Math.pow(gy - j, po)));
            bd = Math.floor(Math.sqrt(Math.pow(bx - i, po) + Math.pow(by - j, po)));
            maxd = 1400;
            r = Math.floor((1 - rd / maxd) * 255);
            g = Math.floor((1 - gd / maxd) * 255);
            b = Math.floor((1 - bd / maxd) * 255);

            var index = (i + j * canvas.width) * 4;

            canvasData.data[index + 0] = r;
            canvasData.data[index + 1] = g;
            canvasData.data[index + 2] = b;
            canvasData.data[index + 3] = 255;

          }
        }

        ctx.putImageData(canvasData, 0, 0);
      }
      
      // Use setInterval to display the images sequentially (every 1000 m/s (every second))
      let showImg = setInterval(doit, 1000);
    })();
  </script>
</body>