Javascript 优化画布动画的过程

Javascript 优化画布动画的过程,javascript,html,animation,Javascript,Html,Animation,我正在开发一个小的web应用程序来模拟伊辛的磁性模型。我发现,动画在运行几秒钟后会明显减慢,并且在5秒钟后也不会像我希望的那样通过命令循环: setInteval(main, 500) 我添加了开始和停止按钮。当我停止动画,然后重新启动它时,它会以通常的速度重新开始,但再次变慢 我的问题是:我可以采取什么步骤来排除故障并优化画布动画的性能?我希望减少或减轻这种减速效应 JS代码: window.onload = function() { var canvas = doc

我正在开发一个小的web应用程序来模拟伊辛的磁性模型。我发现,动画在运行几秒钟后会明显减慢,并且在5秒钟后也不会像我希望的那样通过命令循环:

setInteval(main, 500)
我添加了开始和停止按钮。当我停止动画,然后重新启动它时,它会以通常的速度重新开始,但再次变慢

我的问题是:我可以采取什么步骤来排除故障并优化画布动画的性能?我希望减少或减轻这种减速效应

JS代码:

window.onload = function() {
            var canvas = document.getElementById("theCanvas");
            var context = canvas.getContext("2d");
            var clength = 100;
            var temperature = 2.1;
            var playAnim = true;
            canvas.width = clength;
            canvas.height = clength;
            var imageData = context.createImageData(clength, clength);

            document.getElementById("stop").addEventListener("click",function(){playAnim=false;});
            document.getElementById("start").addEventListener("click",function(){playAnim=true;});

            function init2DArray(xlen, ylen, factoryFn) {
                //generates a 2D array of xlen X ylen, filling each element with values defined by factoryFn, if called.
                var ret = []
                for (var x = 0; x < xlen; x++) {
                    ret[x] = []
                    for (var y = 0; y < ylen; y++) {
                        ret[x][y] = factoryFn(x, y)
                    }
                }
                return ret;
            }


            function createImage(array, ilen, jlen) {
                for (var i = 0; i < ilen; i++) {
                    for (var j = 0; j < jlen; j++) {
                        var pixelIndex = (j * ilen + i) * 4;

                        if (array[i][j] == 1) {
                            imageData.data[pixelIndex] = 0;     //r
                            imageData.data[pixelIndex+1] = 0;   //g
                            imageData.data[pixelIndex+2] = 0;   //b
                            imageData.data[pixelIndex+3] = 255; //alpha (255 is fully visible)
                            //black
                        } else if (array[i][j] == -1) {
                            imageData.data[pixelIndex] = 255;   //r
                            imageData.data[pixelIndex+1] = 255; //g
                            imageData.data[pixelIndex+2] = 255; //b
                            imageData.data[pixelIndex+3] = 255; //alpha (255 is fully visible)
                            //white
                        }
                    }
                }
            }

            function dU(i, j, array, length) {
                var m = length-1;
                //periodic boundary conditions
                if (i == 0) { //top row
                   var top = array[m][j]; 
                } else {
                    var top = array[i-1][j];
                }
                if (i == m) { //bottom row
                    var bottom = array[0][j];
                } else {
                    var bottom = array[i+1][j];
                }
                if (j == 0) { //first in row (left)
                    var left = array[i][m];
                } else {
                    var left = array[i][j-1];
                }
                if (j == m) { //last in row (right)
                    var right = array[i][0];
                } else {
                    var right = array[i][j+1]
                }
                return 2.0*array[i][j]*(top+bottom+left+right); //local magnetization
            }  

            function randInt(max) {
                return Math.floor(Math.random() * Math.floor(max));
            }


            var myArray = init2DArray(clength, clength, function() {var c=[-1,1]; return c[Math.floor(Math.random()*2)]}); //creates a 2D square array populated with -1 and 1


            function main(frame) {
                if (!playAnim){return;} // stops
                window.requestAnimationFrame(main);


                createImage(myArray, clength, clength);
                context.clearRect(0,0,clength,clength);
                context.beginPath();
                context.putImageData(imageData,0,0);

                for (var z = 0; z < 10*Math.pow(clength,2); z++) {
                    i = randInt(clength-1);
                    j = randInt(clength-1);

                    var deltaU = dU(i, j, myArray, clength);

                    if (deltaU <= 0) {
                        myArray[i][j] = -myArray[i][j];
                    } else {
                        if (Math.random() < Math.exp(-deltaU/temperature)) {
                            myArray[i][j] = -myArray[i][j];
                        }
                    }
                } 
            }
            var timer = setInterval(main, 500);                   
        }
window.onload=function(){
var canvas=document.getElementById(“theCanvas”);
var context=canvas.getContext(“2d”);
变异长度=100;
var温度=2.1;
var playAnim=真;
canvas.width=长度;
canvas.height=长度;
var imageData=context.createImageData(clength,clength);
document.getElementById(“stop”).addEventListener(“单击”,函数(){playAnim=false;});
document.getElementById(“开始”).addEventListener(“单击”,函数(){playAnim=true;});
函数init2DArray(xlen、ylen、factoryFn){
//生成xlen X ylen的二维数组,如果调用,则用factoryFn定义的值填充每个元素。
var ret=[]
对于(变量x=0;x如果(deltaU在一个时间间隔内运行您的逻辑,在这个时间间隔内的渲染以毫秒为单位,
500
相当于0.5秒,而不是5秒。@ChrisG谢谢!发现了这个错误,但这并不能解释为什么它没有循环。理想情况下,我希望每个循环都有一个新的模拟动画。@dumpythepickler它正在循环,这就是。)这也是为什么它一直变慢的原因:
main
安排自己的下一个调用,这意味着一旦间隔时间过去,我们现在每帧有两个
main
调用。然后是三个,然后是四个。我仍然不确定间隔的意义是什么;现在替换
var timer=setInterval(main,500);
使用
main()
并从那里开始:@dumpythepickler如果要减慢动画速度,只需删除
窗口。requestAnimationFrame(main);
来自
main()
。这将根据间隔进行更新和绘制: