我有一个包含多个<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的新手,很抱歉,如果这是一个明显的,仍然感觉我的方式。在正确的方向指导非常感谢!感谢。
答案 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 );
希望这会有所帮助:)