Javascript setInterval随机停止

时间:2016-07-08 19:36:07

标签: javascript html5 html5-canvas setinterval

我正在使用setInterval来调用一个在HTML5画布上动画分形的函数。还有一个滑块允许用户改变分形的质量。一切正常,直到我开始更改滑块。当我改变它时,分形动画变得不稳定,最终“drawFractal”函数停止被调用。 这是滑块HTML:

<input type="range" id="qualitySlider" min="1" max="10"></input>

这是javascript(它只是生成一个分形):

var count = 0.5;

var slider = document.getElementById("qualitySlider");
var g = document.getElementById("drawingCanvas").getContext("2d");

function drawFractal() {
    var cellSize = Math.ceil(slider.value);
    //canvas is 700 by 400
    g.fillStyle = "black";
    g.clearRect(0, 0, 700, 400);

    //Eveything from here to the end of this function generates the fractal
    var imagC = Math.cos(count)*0.8;
    var realC = Math.sin(count)*0.5;
    for (x = 0; x < 700; x+=cellSize) {
        for (y = 0; y < 400; y+=cellSize) {
            var yCoord = (x / 700.0 - 0.5)*3;
            var xCoord = (y / 400.0 - 0.5)*3;
            var real = xCoord;
            var imag = yCoord;

            var broken = 0;
            for (i = 0; i < 8; i++) {
                var temp = real*real - imag*imag + realC;
                imag = 2*imag*real + imagC;
                real = temp;
                if (real*real + imag*imag >= 4) {
                    broken = true;
                    break;
                }
            }

            if (!broken) {
                g.fillRect(x, y, cellSize, cellSize);
            }
        }
    }
    count = count + 0.04;
}

setInterval(drawFractal, 60);

我只需要每60毫秒可靠地调用“drawFractal”函数。

2 个答案:

答案 0 :(得分:0)

这是我改进的代码。我只是使用requestAnimationFrame以递归方式调用&#34; drawFractal&#34;功能。我还使用setTimeout函数将动画限制为24帧/秒。

var count = 0.5;

var qualitySlider = document.getElementById("qualitySlider");
var g = document.getElementById("drawingCanvas").getContext("2d");

function drawFractal() {
    var cellSize = Math.ceil(qualitySlider.value);
    //canvas is 700 by 400
    g.fillStyle = "black";
    g.clearRect(0, 0, 700, 400);
    var imagC = Math.cos(count)*0.8;
    var realC = Math.sin(count)*0.5;
    for (x = 0; x < 700; x+=cellSize) {
        for (y = 0; y < 400; y+=cellSize) {
            var yCoord = (x / 700.0 - 0.5)*3;
            var xCoord = (y / 400.0 - 0.5)*3;
            var real = xCoord;
            var imag = yCoord;

            var broken = 0;
            for (i = 0; i < 8; i++) {
                var temp = real*real - imag*imag + realC;
                imag = 2*imag*real + imagC;
                real = temp;
                if (real*real + imag*imag >= 4) {
                    broken = true;
                    break;
                }
            }

            if (!broken) {
                g.fillRect(x, y, cellSize, cellSize);
            }
        }
    }
    count = count + 0.04;
    setTimeout(function() {
        requestAnimationFrame(drawFractal);
    }, 41);
}

drawFractal();

答案 1 :(得分:-2)

您正在使用setInterval()每60 ms调用一次drawFractal,然后每次执行drawFractal时,您都需要再次调用setInterval() ,这是不必要的。你现在有两个计时器试图每60毫秒绘制一次分形...然后你会有4个,然后是8个等等。

您需要(1)在程序执行开始时调用setInterval()一次并且不再调用它,或者(2)切换到使用setTimeout(),并在每个drawFractal()的末尾调用它。

我使用第二个选项,以防万一你的分形画需要超过60毫秒。