#javascript #jquery #image #html5-canvas
Вопрос:
У меня есть приложение, которое должно сгенерировать пару тысяч изображений. Я делаю это с помощью набора предварительно загруженных png (действующих как прозрачные слои) и закадрового холста. Я рисую изображения на холсте, преобразую их в большой двоичный объект, а затем записываю изображение в div, используя пользовательский класс под названием Images.
Сначала я хочу показать панель загрузки и очистить старые изображения, но перед обновлением dom возникает задержка в 3-5 секунд, даже если код «пустой()» и «показать()» находится в начале запроса на щелчок.
Есть ли что-то, что я делаю неправильно в отношении асинхронности или обещаний, из-за чего dom не обновляется немедленно?
Вот некоторые из кодов:
// Generate Images
$("#generate_images").click(function(){
// Show loading bar
$("#progress_bar .progress-bar").css("width", "0%");
$("#progress_bar").show(0);
// Show loading spinner
$("#loading").show(0);
$("#images").empty();
console.log("Generating Images");
$.each(images, function(id, image){
// Sort traits (png layers)
var traits = Object.values(image.traits).sort((a, b) => {
return a.z_index - b.z_index;
});
images[id].layers = [];
$.each(traits, function(trait_idx, trait){
images[id].layers.push(preloaded_images[trait.variant_id])
});
});
// Create canvas
var canvas = new OffscreenCanvas(1200, 1200);
var context = canvas.getContext("2d");
console.log("Generating canvases.");
$.each(images, function(id, image){
// Clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Draw each image layer
$.each(images.layers, function(src, layer){
context.drawImage(layer, 0, 0);
});
// Add imageData to screen
canvas.convertToBlob().then(function(blob) {
// Do something with the blob like render to the screen
});
});
});
Любые мысли о том, как сделать это более эффективным, также будут оценены.
Ответ №1:
Создание тысячи изображений-это не то, для чего обязательно предназначен браузер, но вам нужно дать DOM возможность обновить, поэтому добавьте тайм-аут
- Соберите то, что вы хотите сделать, в массив
- Не зацикливайтесь, а вместо этого делайте
function generate() {
if (arrayCounter >= array.length) return
canvas.convertToBlob().then(function(blob) {
if (success) {
arrayCounter
generate()
}
}
}
collect()
generate()
Комментарии:
1. Это не слишком детерминировано. Есть ли способ сделать это, чтобы знать, когда dom завершит обновление?
2. Это возможно с наблюдателем, но, на мой взгляд, не обязательно. Достаточно тайм-аута в 10 мс