Как запустить setInterval () на нескольких холстах одновременно? - PullRequest
1 голос
/ 12 марта 2010

У меня есть страница с несколькими элементами <canvas>.

Я передаю идентификатор холста и массив данных функции, которая затем захватывает информацию холста и передает данные в функцию 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 ]

3 голосов
/ 12 марта 2010

Проблема связана с , как работают замыкания . Замыкания не получают копию данных, они получают активную ссылку на них. Поэтому, когда функция запускается позже, она ссылается на живую копию из i и т. Д., Которая перешла с тех пор, как вы установили вызов.

Вы можете исправить это так:

drawLater(dimensions, data, i);

... с этим определенным в другом месте:

function drawLater(dimensions, data, i) {

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

Это работает, потому что замыкание содержит ссылку на аргументы drawLater, а не на переменные в вашем цикле.

Отдельно: разве вы не должны передавать холст или его идентификатор куда-нибудь?

2 голосов
/ 12 марта 2010

Как draw() узнает, какой холст использовать? Я полагаю из вашего кода, что вы используете глобальную переменную ctx, которая будет перезаписываться при каждом вызове setup(). Поэтому вам нужно изменить draw() и добавить холст для использования в качестве первого параметра.

1 голос
/ 12 марта 2010

Переменные JavaScript: , область действия , а не область блока. Также вам нужно объявить ctx с var, чтобы сделать его локальным, а затем передать его функции рисования.

0 голосов
/ 12 марта 2010

Я думаю, вы сможете заставить его работать, если попробуете следующее:

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

Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...