Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript waiting until an image is fully loaded before continuing script

I've been looking around a lot of JavaScript answers but I haven't found one that really answers my problem yet. What I'm trying to do is load an image, grab the pixel data, perform an analysis, and then load another image to repeat the process.

My problem is that I can't preload all of the images because this script has to be able to work on large amounts of images and preloading could be too resource heavy. So I'm stuck trying to load a new image each time through a loop, but I'm stuck with a race condition between the image loading and the script drawing it to the canvas's context. At least I'm pretty sure that's what is happening because the script will work fine with the images precached (for example if I refresh after loading the page previously).

As you'll see there are several lines of code commented out because I'm incredibly new to JavaScript and they weren't working the way I thought they would, but I didn't want to forget about them if I needed the functionality later.

This is the snippet of code that I believe is giving rise to the problem:

EDIT: So I got my function to work after following a suggestion

 function myFunction(imageURLarray) {
  var canvas = document.getElementById('imagecanvas');
  console.log("Canvas Grabbed");

  if (!canvas || !canvas.getContext) {
    return;
  }

  var context = canvas.getContext('2d');

  if (!context || !context.putImageData) {
    return;
  }

  window.loadedImageCount = 0;
  loadImages(context, canvas.width, canvas.height, imageURLarray, 0);
}

function loadImages(context, width, height, imageURLarray, currentIndex) {
  if (imageURLarray.length == 0 || imageURLarray.length == currentIndex) {
    return false;
  }
  if (typeof currentIndex == 'undefined') {
    currentIndex = 0;
  }

  var currentimage = new Image();
  currentimage.src = imageURLarray[currentIndex];

  var tempindex = currentIndex;
  currentimage.onload = function(e) {

    // Function code here

    window.loadedImageCount++;

    if (loadedImageCount == imageURLarray.length) {

      // Function that happens after all images are loaded here
    }
  }
  currentIndex++;
  loadImages(context, width, height, imageURLarray, currentIndex);
  return;
}
like image 732
Braains Avatar asked Jun 04 '13 14:06

Braains


People also ask

How do you show image only when it is completely loaded?

Preload the image and replace the source of the <img /> after the image has finished loading. Show activity on this post. You can use the complete property to check if the image has finished loading.

How can you tell if an image element is loaded on a page?

To determine whether an image has been completely loaded, you can use the HTMLImageElement interface's complete attribute. It returns true if the image has completely loaded and false otherwise. We can use this with naturalWidth or naturalHeight properties, which would return 0 when the image failed to load.

When should JavaScript be loaded?

If you need the functionality incorporated in the script or scripts, like function libraries, available before or during page loading then you should load JavaScript code in the head tag.

How do you check if all images are loaded in jQuery?

To check if an image is loaded successful or not, you can combine the use of jQuery 'load()' and 'error()' event : $('#image1') . load(function(){ $('#result1'). text('Image is loaded!


1 Answers

Maybe this will help:

currentimage.onload = function(e){
    // code, run after image load
}

If it is necessary to wait for the image to load, the following code will load the next image (currentIndex is your "img" variable):

var loadImages = function(imageURLarray, currentIndex){
    if (imageURLarray.length == 0 || imageURLarray.length == currentIndex) return false;
    if (typeof currentIndex == 'undefined'){
       currentIndex = 0;
    }
    // your top code
    currentimage.onload = function(e){
        // code, run after image load
        loadImages(imageURLArray, currentIndex++);
    }
}

Instead of a "for" loop, use for example this function:

loadImages(imageURLarray);
like image 75
maximkou Avatar answered Sep 19 '22 01:09

maximkou