Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for multiple images to load

Tags:

vue.js

I have multiples images to load, and i put them in an Array.

In a loop, i increment a counter when an image is loaded.

When this counter is equal to the Array length of my images, i want to remove the loading indicator.

i dont know why, thats doesnt work.

new Vue({
  el: "#app",
  created() {
    let imageLoaded = 0;
    for (const imageSrc of this.imagesToPreload) {
      if (imageLoaded === this.imagesToPreload.length) {
        console.log("Done !");
        this.loading = false;
      }

      const img = new Image();
      img.src = imageSrc;

      img.onload = () => {
        imageLoaded++;
        console.log(imageLoaded);
      };
    }
  },
  data() {
    return {
      isLoading: true,
      imagesToPreload: [
        "https://placeimg.com/1280/800/any",
        "https://placeimg.com/1280/800/any",
        "https://placeimg.com/1280/800/any"
      ]
    };
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
	<div v-if="isLoading">Loading...</div>
</div>
like image 421
R1pairedas Avatar asked Dec 10 '18 14:12

R1pairedas


1 Answers

Your code will check if the images are loaded immediately after setting the image sources. It won't wait until any of the images are actually loaded.

In my opinion, the best way would be to use promises:

new Vue({
  el: "#app",
  created() {
    const images = this.imagesToPreload.map(imageSrc => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = imageSrc;
        img.onload = resolve;
        img.onerror = reject;
      });
    });

    Promise.all(images).then(() => { 
      console.log("Images loaded!");
      this.isLoading = false;
    }).catch(error => {
      console.error("Some image(s) failed loading!");
      console.error(error.message)
    });
  },
  data() {
    return {
      isLoading: true,
      imagesToPreload: [
        "https://placeimg.com/1280/800/any",
        "https://placeimg.com/1280/800/any",
        "https://placeimg.com/1280/800/any"
      ]
    };
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
     <div v-if="isLoading">Loading...</div>
</div>

Or, try putting a check in the onload callback for each image.

  created() {
    let imageLoaded = 0;
    for (const imageSrc of this.imagesToPreload) {    
      const img = new Image();
      img.src = imageSrc;

      img.onload = () => {
        imageLoaded++;

        if (imageLoaded === this.imagesToPreload.length) {
          console.log("Done !");
          this.isLoading = false;
        }

        console.log(imageLoaded);
      };
    }
  }
like image 193
maxpaj Avatar answered Oct 10 '22 11:10

maxpaj