Dom не обновляется сразу при использовании convertToBlob на закадровом холсте

#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 возможность обновить, поэтому добавьте тайм-аут

  1. Соберите то, что вы хотите сделать, в массив
  2. Не зацикливайтесь, а вместо этого делайте

   function generate() {
    if (arrayCounter >= array.length) return
    canvas.convertToBlob().then(function(blob) {
      if (success) {
        arrayCounter  
        generate()
      }
    }
  }
  collect()
  generate()
 

Комментарии:

1. Это не слишком детерминировано. Есть ли способ сделать это, чтобы знать, когда dom завершит обновление?

2. Это возможно с наблюдателем, но, на мой взгляд, не обязательно. Достаточно тайм-аута в 10 мс