优化画布动画的过程

时间:2018-04-17 21:25:23

标签: javascript html animation

我正在开发一个小型网络应用程序,以模拟Ising的磁力模型。我发现动画在运行几秒钟后动画速度明显减慢,并且它也不会像我想要的那样在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);                   
        }

0 个答案:

没有答案