如何同时在多个画布上运行setInterval()?

时间:2010-03-12 11:28:14

标签: javascript jquery html5 canvas

我有一个包含多个<canvas>元素的页面。

我将画布ID和数据数组传递给函数,该函数然后抓取画布信息并将数据传递到draw()函数,该函数依次处理给定数据并将结果绘制到画布上。到目前为止,非常好。

示例数据阵列;

$(function() {
    setup($("#canvas-1"), [[110,110,100],
                          [180,180,50],
                          [220,280,80]]);

    setup($("#canvas-2"), [[110,110,100],
                          [180,180,50],
                          [220,280,80]]);
});

设置功能;

function setup(canvas, data) {
    ctx = canvas[0].getContext('2d');
    var i = data.length;
    var dimensions = {
        w : canvas.innerWidth(),
        h : canvas.innerHeight()    
    };
    draw(dimensions, data, i);  
}

这完美无缺。运行draw()并填充每个画布。

然而 - 我需要为画布设置动画。一旦我替换上面例子的第8行;

draw(dimensions, data, i);  

setInterval( function() { draw(dimensions, data, i); }, 33 );

它停止工作并且仅绘制最后一个画布(其他画布保持空白)。

我是javascript和canvas的新手,很抱歉,如果这是一个明显的,仍然感觉我的方式。在正确的方向指导非常感谢!感谢。

4 个答案:

答案 0 :(得分:3)

问题与how closures work有关。闭包不会收到数据的副本,它们会收到一个活动的引用。因此,当稍后运行该函数时,它会引用i实时副本等等 - 自设置调用以来已经继续运行。

你可以这样解决:

drawLater(dimensions, data, i);

......在其他地方定义:

function drawLater(dimensions, data, i) {

    setInterval(function() { draw(dimensions, data, i); }, 33 );
}

这是有效的,因为闭包包含对drawLater的参数的引用,而不是对循环中的变量的引用。

另外:你不应该将画布或其ID传递到某个地方吗?

答案 1 :(得分:2)

draw()如何知道要使用哪个画布?我对你的代码的猜测是,你正在使用全局变量ctx,每次调用setup()都会被覆盖。因此,您需要更改draw()并添加画布以用作第一个参数。

答案 2 :(得分:1)

JavaScript变量是function scoped,而不是块作用域。此外,您需要使用ctx声明var以使其成为本地,然后将其传递给绘制函数。

答案 3 :(得分:-2)

如果您尝试以下操作,我认为您应该能够使其发挥作用:

setInterval( 'draw(dimensions, data, i);', 33 );

希望这会有所帮助:)