2013-09-24 4 views
1

Я использую холст HTML5. Я загрузил изображение размером 7 МБ внутри элемента холста. На моей странице есть кнопка ConvertImage:HTML5 Canvas toDataURL() блокирует вызов JavaScript?

var imageUrl; 
$("#ConvertImage").click(function() { 
    $("#Spinner").show(); 
    imageUrl = $("#canvas")[0].toDataURL("image/png;base64;"); 
}); 

Spinner - это просто анимированный gif. Оказывается, Spinner не отображается сразу же, когда я пытаюсь восстановить imageUrl в следующем выражении. Без второй операции прядильщик показан сразу. Похоже, что счетчик показан после завершения операции toDataURL().

Это странно, потому что функция show() выполняется перед операцией toDataURL().

Как исправить эту проблему?

ответ

3

Для обновления вертушку, попытайтесь изменить код таким образом, что создается дополнительное событие обновления.

Вы можете сделать это с помощью setTimeout:

$("#ConvertImage").click(function() { 
    $("#Spinner").show(); 

    /// add an event to be executed in about 100ms 
    setTimeout(function() { 
     imageUrl = $("#canvas")[0].toDataURL(); 
     /// done, optionally call some other function... 
    }, 100); 

}); 

Это даст .show() некоторое время, чтобы закончить и событие для setTimeout будет поставлен в очередь после него.

Возможно, вам потребуется изменить значение, которое я начал здесь (100 мс).

Существует также ошибка в коде, который делает, вероятно, ничего не влияет, но это не больно, чтобы получить это право -

Аргументом для toDataURL файл должен быть только тип, то есть. image/png, image/jpeg, image/webp и т. Д. Базовая часть 64 не должна быть там (вероятно, при копировании типа изображения из существующего data-uri). Как PNG по умолчанию нет необходимости указывать его в любом случае - просто использовать:

var dataUri = myCanvas.toDataURL(); /// default is image/png, also when it cannot 
            /// detect a supported type 

или

var dataUri = myCanvas.toDataURL('image/png'); 
var dataUri = myCanvas.toDataURL('image/jpeg'); 

т.д.

+0

бы чек на '.complete' быть Беттен, чем жестко прописывать произвольное значение 100 мс? – cherouvim

1

Я думаю, что ваша проблема очень похожа на проблему, описанную в следующем вопросе: innerHTML can't be trusted: Does not always execute synchronously.

В принципе, обновления DOM на самом деле не являются «синхронными», что означает, что ваш запрос на отображение счетчика произойдет только после завершения вашего текущего кода.

Вы должны иметь в виду, что выполнение javascript однопоточно, поэтому любое дорогостоящее вычисление просто заморозит ваш пользовательский интерфейс. Отображение счетчика имеет смысл при выполнении длительной асинхронной операции, такой как запрос AJAX, но бесполезно при выполнении синхронной операции блокировки, например, toDataURL, поскольку пользовательский интерфейс не имеет возможности обновляться до его завершения.

Если вам необходимо выполнить длинный синхронный код, то посмотрите на Web Workers: http://www.html5rocks.com/en/tutorials/workers/basics/

Смежные вопросы