Javascript 为什么我的像素操作脚本这么慢?

Javascript 为什么我的像素操作脚本这么慢?,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我试图创建一些蓝色波浪,但如果我运行它,浏览器将释放。只有当我将画布的大小减小到80和60时,它才会起作用 <canvas id="canvas" width="800" height="600"></canvas> 脚本: var canvas=document.getElementById('canvas'), ctx = canvas.getContext('2d'); var imageData = ctx.createImageData(canvas.wi

我试图创建一些蓝色波浪,但如果我运行它,浏览器将释放。只有当我将画布的大小减小到80和60时,它才会起作用

<canvas id="canvas" width="800" height="600"></canvas>

脚本:

var canvas=document.getElementById('canvas'), ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(canvas.width, canvas.height);

for(var i=0; i<imageData.width; i++) {
    for(var j=0; j<imageData.height; j++) {
        imageData.data[((imageData.width * j) + i) * 4] = 0;
        imageData.data[((imageData.width * j) + i) * 4+1] = 0;
        imageData.data[((imageData.width * j) + i) * 4+2] = 127*Math.sin(i/100)+128;
        imageData.data[((imageData.width * j) + i) * 4+3] = 255;
        ctx.putImageData(imageData, 0, 0);
    }
}
var canvas=document.getElementById('canvas'),ctx=canvas.getContext('2d');
var imageData=ctx.createImageData(canvas.width、canvas.height);

对于(var i=0;i它之所以慢,一个原因是因为您正在冗余地执行某些计算

var value = (imageData.width * j) + i); // <--- cache this value

var值=(imageData.width*j)+i);// 查看疯狂快速测试

可以写成:

    tmp = ((imageData.width * j) + i) * 4;
    imageData.data[tmp] = 0;
    imageData.data[tmp + 1] = 0;
    imageData.data[tmp + 2] = 127*Math.sin(i/100)+128;
    imageData.data[tmp + 3] = 255;

我还包括了not_john将繁重的任务移出循环的想法

主要的减速是因为每次迭代都要绘制图像

移动这条线

ctx.putImageData(imageData, 0, 0);

在你的循环之外。

嗯,那是很多像素。80 * 60 = 4800; 800*600=480000在这些数字下,即使是animgif也更可行……为什么要在内部循环中执行
putImageData
?在写入所有数据之后,这样做还不够吗?尝试将内部循环不变量从循环中去掉:
Math.sin(i/100)+128
。无需在每个内部循环迭代中反复计算。因此,与其计算它的
imageData.width*imageData.height
次,不如只计算它的
imageData.width
次。
    tmp = ((imageData.width * j) + i) * 4;
    imageData.data[tmp] = 0;
    imageData.data[tmp + 1] = 0;
    imageData.data[tmp + 2] = 127*Math.sin(i/100)+128;
    imageData.data[tmp + 3] = 255;
ctx.putImageData(imageData, 0, 0);