Kevmon Kevmon - 3 months ago 13
Javascript Question

After All Images Load, Image Tag, Image Object, and Background Image

I have a background image, an

<img>
, and 5 separate canvas layers (making up 5 customizable parts of the hammock shown). I need to wait for all 3 of these images to load fully into their respective
{display:none;}
elements, and then fade them all in at once.

After some research, I found the library imagesLoaded. In the documentation, I know I can use it for an and a background image, but I'm not sure about an image object (which I'm using to load the canvas images).

Problems:

1) It still loads them separately and fadeIn doesn't wait.

2) In console,
count
increments at odd numbers for some reason, e.g. 1, 3, 5, 7, 11

3) Also, any of these images could already be cached upon load.

I know this code isn't the cleanest or most efficient. I plan to clean it up after getting the basic concept down. If imagesLoaded isn't the best way to go, what would you recommend? I just want something that works.

JSFiddle

HTML:

<div id="container">
<div id="logo"><img src="https://upload.wikimedia.org/wikipedia/commons/8/82/Dell_Logo.png"/></div>
<canvas id="canvas1" width="1000" height="1000"></canvas>
<canvas id="canvas2" width="1000" height="1000"></canvas>
<canvas id="canvas3" width="1000" height="1000"></canvas>
<canvas id="canvas4" width="1000" height="1000"></canvas>
<canvas id="canvas5" width="1000" height="1000"></canvas>
</div>


CSS:

#container {
height:1000px;
width:1000px;
position: relative;
display:none;
background-position: top left;
background-repeat: no-repeat;
background-size: cover;
}
#logo {
width: 200px;
height: 200px;
position:absolute;
top: 50px;
left: 400px;
}
img {
max-width: 100%;
}
#canvas1 {
position: absolute;
top:0;
left:0;
display:none;
}
#canvas2 {
position:absolute;
top:0;
left:0;
display:none;
}
#canvas3 {
position:absolute;
top:0;
left:0;
display:none;
}
#canvas4 {
position:absolute;
top:0;
left:0;
display:none;
}
#canvas5 {
position:absolute;
top:0;
left:0;
display:none;
}


JavaScript:

var canvas1 = document.getElementById('canvas1');
var canvas2 = document.getElementById('canvas2');
var canvas3 = document.getElementById('canvas3');
var canvas4 = document.getElementById('canvas4');
var canvas5 = document.getElementById('canvas5');
var context1 = canvas1.getContext('2d');
var context2 = canvas2.getContext('2d');
var context3 = canvas3.getContext('2d');
var context4 = canvas4.getContext('2d');
var context5 = canvas5.getContext('2d');

var count = 0;

var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
var img4 = new Image();
var img5 = new Image();

img1.src = 'https://cdn.shopify.com/s/files/1/1408/4812/t/11/assets/single-side-main-burgundy.png';
img2.src = 'https://cdn.shopify.com/s/files/1/1408/4812/t/11/assets/single-side-secondary-aqua.png';
img3.src = 'https://cdn.shopify.com/s/files/1/1408/4812/t/11/assets/single-side-pouch1-aqua.png';
img4.src = 'https://cdn.shopify.com/s/files/1/1408/4812/t/11/assets/single-side-pouch2-aqua.png';
img5.src = 'https://cdn.shopify.com/s/files/1/1408/4812/t/11/assets/single-side-pouch3-aqua.png';


$("#container").css("background-image", "url(http://www.hotel-r.net/im/hotel/ba/house-3.jpg)");
img1.onload = function() {
context1.drawImage(img1, 0 , 0, 1000, 1000);
}
img2.onload = function() {
context2.drawImage(img2, 0 , 0, 1000, 1000);
}
img3.onload = function() {
context3.drawImage(img3, 0 , 0, 1000, 1000);
}
img4.onload = function() {
context4.drawImage(img4, 0 , 0, 1000, 1000);
}
img5.onload = function() {
context5.drawImage(img5, 0 , 0, 1000, 1000);
}

function fadeInAll(speed) {
$("#container").fadeIn(speed);
$("#canvas1").fadeIn(speed);
$("#canvas2").fadeIn(speed);
$("#canvas3").fadeIn(speed);
$("#canvas4").fadeIn(speed);
$("#canvas5").fadeIn(speed);
$('#logo').fadeIn(speed);
}

$('#container').imagesLoaded( { background: true }, function() {
count++;
afterAllLoading();
});
$('#logo').imagesLoaded( function() {
count++;
afterAllLoading();
});
$('img1').imagesLoaded( function() {
count++;
afterAllLoading();
});
$('img2').imagesLoaded( function() {
count++;
afterAllLoading();
});
$('img3').imagesLoaded( function() {
count++;
afterAllLoading();
});
$('img4').imagesLoaded( function() {
count++;
afterAllLoading();
});
$('img5').imagesLoaded( function() {
count++;
afterAllLoading();
});

function afterAllLoading() {
console.log(count++);
if (count >= 7) {
fadeInAll(1000);
}
}

Answer

Ironically, your issue is with console.log(count++). This will increment the count as well, making it hit 7 before desired. So, only half of the images will be loaded by the time your fadeInAll method is called. You should call console.log(count) instead.

That will probably work - but I suggest simplifying the code a bit by just having a parent container element around all of the canvases, then setting that parent's display to none. Then, you need only worry about fading in and out one parent element instead of 7 children, and they will always fade in and out together.