Живое обновление JavaScript canvas
Я написал генератор фрактальных изображений, который может работать от долей секунд до нескольких минут, в зависимости от количества итераций для каждого пикселя. В текущей версии пользователь должен ждать, пока изображение полностью не отобразится, пока не увидит результат. В течение этого времени пользовательский интерфейс браузера блокируется, и Firefox будет отображать предупреждающее сообщение каждые 10 секунд, спрашивая, следует ли продолжить, отладить или остановить скрипт.
Вопрос: можно ли отображать обновления содержимого холста во время работы скрипта?
2 ответа
Да
Пользовательский интерфейс блокируется до тех пор, пока не будет возвращен текущий вызов (обычно запускаемый событием). Когда функция возвращает любые изменения в DOM, они обновляются, и следующее событие, если оно есть, помещается в стек вызовов и вызывается, в противном случае механизм javascript просто ожидает событие.
Вы можете использовать setTimeout, чтобы запланировать событие, обработать несколько пикселей, установить тайм-аут, снова выйти и так далее.
Пример просто с точки зрения логического потока
var complete = false;
var pixels = 100000;
var pixelsPerCall = 1000;
function addPixels(){
// process x number of pixels
var i = pixelsPerCall;
while(i-- && pixels--){
// do a pixel
}
if(pixels === 0){
complete = true;
}
if(! complete){
setTimeout(addPixels,0);
}
}
addPixels();
Хотя для такого типа приложений лучше всего использовать webWorkers. В зависимости от количества ядер, которые есть у машины, вы можете значительно увеличить пропускную способность. Например, процессор I7 с 8 ядрами выполнит работу в 8 раз быстрее. Также веб-работники не блокируют DOM, поэтому могут работать так долго, как вы хотите.
Один из возможных подходов состоит в том, чтобы разбить ваши вычисления на куски, запускать каждый шаг с setTimeout
/ setImmediate
Обновите холст и запустите другой кусок.
Это не только обновляет холст постепенно, но также мешает браузеру жаловаться на долго выполняющийся скрипт.