Why does JavaScript not load all pictures? - javascript

I have this code snippet below...
You can see I am trying to load 9 pictures.
When I execute the following code, I only get an alert 7 times and the console does never log "all images loaded". Why is this?
var images = [];
edge_topleft = new Image(); images.push(edge_topleft);
edge_topright = new Image(); images.push(edge_topright);
edge_bottomleft = new Image(); images.push(edge_bottomleft);
edge_bottomright = new Image(); images.push(edge_bottomright);
edge_cross = new Image(); images.push(edge_cross);
block = new Image(); images.push(block);
ice = new Image(); images.push(ice);
way_lr = new Image(); images.push(way_lr);
way_ud = new Image(); images.push(way_ud);
var len = images.length;
var counter = 0;
[].forEach.call(images, function( img ) {
img.addEventListener( 'load', incrementCounter, false);
} );
function incrementCounter() {
counter++;
alert(counter);
if ( counter === len ) {
console.log("all images loaded");
}
}
edge_topleft.src = "https://dummyimage.com/10";
edge_topright = "https://dummyimage.com/20";
edge_bottomleft = "https://dummyimage.com/30";
edge_bottomright.src = "https://dummyimage.com/40";
edge_cross.src = "https://dummyimage.com/50";
block.src = "https://dummyimage.com/60";
ice.src = "https://dummyimage.com/70";
way_lr.src = "https://dummyimage.com/80";
way_ud.src = "https://dummyimage.com/90";
Here is the fiddle: https://jsfiddle.net/hnoaj8bg/
Anybody that knows what I'm doing wrong?

Related

JavaScript array for an image gallery with next and prev functions

var spanishAdventure = new Array();
spanishAdventure[0] = new Image();
spanishAdventure[0].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26756508_1743696655674610_7179458580676129491_o.jpg?_nc_cat=0&oh=f16a2edf4ee735e66b6dab095b7fb43c&oe=5B6B32B3';
spanishAdventure[1] = new Image();
spanishAdventure[1].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26758659_1743696569007952_4447096103197624856_o.jpg?_nc_cat=0&oh=a7f015a6709fa9a26f06b07fe9782999&oe=5B6A180E';
spanishAdventure[2] = new Image();
spanishAdventure[2].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678421_1743695449008064_7298258449829506874_o.jpg?_nc_cat=0&oh=d8fb71ad599a0a630f4d118c1d8be6ca&oe=5B6E0AFD';
spanishAdventure[3] = new Image();
spanishAdventure[3].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678110_1743696009008008_4042393389305650172_o.jpg?_nc_cat=0&oh=7d6afafd399c4a2d5d8f0747d59d8353&oe=5B73557C';
spanishAdventure[4] = new Image();
spanishAdventure[4].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26756324_1743697449007864_8430059194945119796_o.jpg?_nc_cat=0&oh=5c93856d22087dbf550fc98dfd7a79ce&oe=5B5FBF15';
spanishAdventure[5] = new Image();
spanishAdventure[5].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678350_1743697612341181_2805503461338827658_o.jpg?_nc_cat=0&oh=1e6d3b0c44b783742de688cedacccc20&oe=5B6E31BF';
spanishAdventure[6] = new Image();
spanishAdventure[6].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26841396_1743696739007935_7256143030060966136_o.jpg?_nc_cat=0&oh=d0b9cbe4f3920af54083ea12d2d19b40&oe=5B63A5E7';
var imageCount = 0;
var totalImage = spanishAdventure.length -1; //array length starting from 0
var img = document.getElementById('mySlides'); //HTML img element which image will be displayed
function imagePrev() {
imgCount-- ;
img.src =spanishAdventure[imageCount].src;
if (imageCount < 0) {
img.src = spanishAdventure[totalImage].src;
break;
}
}
function imageNext() {
imgCount++ ;
img.src =spanishAdventure[imageCount].src;
if (imageCount > totalImage) {
img.src = spanishAdventure[0].src;
break;
}
}
Hi Guys,
I'm currently trying to create an image gallery using Javascript image array and functions that will be called upon to create a gallery in an image element in my original HTML file (not shown). Do you see anything wrong with the js syntax and code for the next and previous functions as they seem to not work when called upon in the html file. I'm a newbie so some enlightening pointers would be fab.
mySlides is the id for an HTML img element.
Cheers,
Liam
As #Titus said, change imageCount to imgCount, or vice-versa
Remove break; from imagePrev and imageNext. It's not doing anything useful.
Build logic to keep imageCount (or imgCount) within the range of your image array.
You don't need to instantiate images to store your source urls. The urls are just text, so they could be put directly into an array, like spanishAdventure = ['urlText1', 'urlText2', ...]
var spanishAdventure = new Array();
spanishAdventure[0] = new Image();
spanishAdventure[0].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26756508_1743696655674610_7179458580676129491_o.jpg?_nc_cat=0&oh=f16a2edf4ee735e66b6dab095b7fb43c&oe=5B6B32B3';
spanishAdventure[1] = new Image();
spanishAdventure[1].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26758659_1743696569007952_4447096103197624856_o.jpg?_nc_cat=0&oh=a7f015a6709fa9a26f06b07fe9782999&oe=5B6A180E';
spanishAdventure[2] = new Image();
spanishAdventure[2].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678421_1743695449008064_7298258449829506874_o.jpg?_nc_cat=0&oh=d8fb71ad599a0a630f4d118c1d8be6ca&oe=5B6E0AFD';
spanishAdventure[3] = new Image();
spanishAdventure[3].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678110_1743696009008008_4042393389305650172_o.jpg?_nc_cat=0&oh=7d6afafd399c4a2d5d8f0747d59d8353&oe=5B73557C';
spanishAdventure[4] = new Image();
spanishAdventure[4].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26756324_1743697449007864_8430059194945119796_o.jpg?_nc_cat=0&oh=5c93856d22087dbf550fc98dfd7a79ce&oe=5B5FBF15';
spanishAdventure[5] = new Image();
spanishAdventure[5].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26678350_1743697612341181_2805503461338827658_o.jpg?_nc_cat=0&oh=1e6d3b0c44b783742de688cedacccc20&oe=5B6E31BF';
spanishAdventure[6] = new Image();
spanishAdventure[6].src = 'https://scontent.flhr4-1.fna.fbcdn.net/v/t31.0-8/26841396_1743696739007935_7256143030060966136_o.jpg?_nc_cat=0&oh=d0b9cbe4f3920af54083ea12d2d19b40&oe=5B63A5E7';
var imageCount = 0;
var totalImage = spanishAdventure.length -1; //array length starting from 0
var img = document.getElementById('mySlides'); //HTML img element which image will be displayed
function imagePrev() {
imageCount > 0 ? imageCount-- : imageCount = 6;
img.src =spanishAdventure[imageCount].src;
}
function imageNext() {
imageCount < 6 ? imageCount++ : imageCount = 0;
img.src =spanishAdventure[imageCount].src;
}
<img id="mySlides" />
<button onClick="imagePrev()">Prev</button>
<button onClick="imageNext()">Next</button>

i want to know when the images have been loaded in memory

i have this function to create new images to load them in memory
function preloadImgs() {
var imgDomain = "http://imgs.domain/";
if (document.images) {
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
img1.src = imgDomain + "images/1/cover.jpg";
img2.src = imgDomain + "images/2/cover.jpg";
img3.src = imgDomain + "images/3/cover.jpg";
} }
// initialize the function
preloadImgs()
i need a way to know when all images in preloadImgs() function have been loaded , how can i achive that using the same code that i have provided ?
You can use a promise pattern.
https://developers.google.com/web/fundamentals/getting-started/primers/promises
Although these aren't natively supported everywhere, jQuery (tagged) provides an implementation:
https://api.jquery.com/promise/
Combined with img.onload to resolve the promises you can respond to an array of promises by:
var arrayOfPromises = [];
var $deferred = $.Deferred();
var img = new Image();
img.onload = function() {
// Check your support needs # http://caniuse.com/#search=naturalWidth
if (img.naturalWidth && img.naturalHeight) {
$deferred.resolve()
} else {
$deferred.reject();
}
};
img.onerror = $deferred.reject;
img.src = 'someimage.png';
arrayOfPromises.push($deferred);
$.when.apply($, arrayOfPromises).then(function() {
// your callback, images all loaded
alert('OK')
}, function() {
// Any failed image load occur
alert('FAIL')
});

Canvas Clearing After Multiple DrawImage

I have been trying to draw a tile-like map to the canvas, although if i try to draw the same sprite twice, it will only render the final call of drawImage. Here is my code if it helps :
window.onload = function(){
function get(id){
return document.getElementById(id);
}
var canvas = get("canvas");
ctx = canvas.getContext("2d");
canvas.width = 160;
canvas.height = 160;
grass = new Image();
water = new Image();
grass.src = "res/Grass.png";
water.src = "res/Water.png";
path = {
draw: function(image,X,Y){
X = (X*32)-32;
Y = (Y*32)-32;
image.onload = function(){
ctx.drawImage(image,X,Y);
}
},
}
path.draw(water,2,2);
path.draw(grass,1,2);
path.draw(grass,1,1);
path.draw(water,2,1);
}
You're overwriting onload on the image next time you call it.
Think of it this way:
var image = {
onload: null
};
// Wait for the image to "load"
// Remember, onload is asynchronous so it won't be called until the rest of
// your code is done and the image is loaded
setTimeout(function() {
image.onload();
}, 500);
image.onload = function() {
console.log('I will never be called');
};
image.onload = function() {
console.log('I overwrite the previous one');
};
Instead, you might try waiting for your images to load then do the rest of your logic.
var numOfImagesLoading = 0;
var firstImage = new Image();
var secondImage = new Image();
// This is called when an image finishes loading
function onLoad() {
numOfImagesLoading -= 1;
if (numOfImagesLoading === 0) {
doStuff();
}
}
function doStuff() {
// This is where you can use your images
document.body.appendChild(firstImage);
document.body.appendChild(secondImage);
}
firstImage.src = 'http://placehold.it/100x100';
firstImage.onload = onLoad;
numOfImagesLoading += 1;
secondImage.src = 'http://placehold.it/200x200';
secondImage.onload = onLoad;
numOfImagesLoading += 1;

JavaScript image loader isn't working

I am trying to make really simple image loader for my game but I can't find out why this isn't working.. Here is my code:
window.onload = function() {
var canvas = document.getElementById('gameCanvas');
var ctx = canvas.getContext('2d');
var images = [];
function loadImages(imageFiles) {
var loadedImages = [];
for(var i = 0; i < imageFiles.length; i++) {
var image = new Image();
image.onload = function() {
alert("Loaded");
}
image.src = imageFiles[i];
loadedImages[i] = image;
}
return loadedImages;
}
function init() {
images = loadImages(['img/1.png', 'img/2.png']);
main();
}
function main() {
ctx.drawImage(images[1], 0,0);
}
init();
}
All I see is blank canvas without an image.
Use Promise, The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.
Promise.all(), The Promise.all(iterable) method returns a promise that resolves when all of the promises in the iterable argument have resolved.
function loadImages(imageFiles) {
var promiseArr = [];
for (var i = 0; i < imageFiles.length; i++) {
var eachPromise = new Promise(function(resolve, reject) {
var image = new Image();
image.onload = function() {
alert('Loaded!');
resolve();
}
image.src = imageFiles[i];
});
promiseArr.push(eachPromise);
}
return promiseArr;
}
function init() {
var AllImages = ['https://www.google.co.in/logos/doodles/2016/earth-day-2016-5741289212477440.2-5643440998055936-ror.jpg', 'https://www.google.co.in/logos/doodles/2016/earth-day-2016-5741289212477440.3-5700735861784576-ror.jpg'];
var allPromises = loadImages(AllImages);
Promise.all(allPromises).then(function() {
alert('All Loaded');
main();
});
}
function main() {}
init();
try replacing
image.onload = function() {
alert("Loaded");
}
with
if(i==1){
image.onload = function() {
main();
}}
when the second image is loaded, your function is called
then edit the code to suit your needs
I will edit more in a while
Images are loaded asynchronously so when you try to read the file in main, the image still is loading. So you need to wait until all the images are loaded.
window.addEventistener("load", function() {
var canvas = document.getElementById('gameCanvas');
var ctx = canvas.getContext('2d');
var images = [];
function loadImages(imageFiles, completeFnc) {
var loadedImages = [],
loadedCnt = 0;
for(var i = 0; i < imageFiles.length; i++) {
var image = new Image();
image.onload = function() {
loadedCnt++; //increment the count
if(loadedCnt==imageFiles.length) { //if count equals total, fire off callback
completeFnc();
}
};
image.onerror = function () {
alert("There was a problem loading the images");
};
image.src = imageFiles[i];
loadedImages[i] = image;
}
return loadedImages;
}
function init() {
images = loadImages(['img/1.png', 'img/2.png'], main);
}
function main() {
ctx.drawImage(images[1], 0,0);
}
init();
});
This should work better
var images = ['img/1.png', 'img/2.png'], loadedImages = [], canvas,ctx, idx=0:
function main() {
ctx.drawImage(images[1], 0, 0);
}
function loadImages() {
if (loadedImages.length == images.length) {
main();
return;
}
var image = new Image();
image.onload = function() {
loadedImages.push(this);
loadImages();
idx++;
}
image.src = imageFiles[idx];
}
function init() {
canvas = document.getElementById('gameCanvas');
ctx = canvas.getContext('2d');
loadImages();
}
window.onload = function() {
init();
}
You need to push items into an array. Replace
loadedImages[i] = image;
with
loadedImages.push(image);

How can I load an array of images to be faded?

I have the following code where I am loading only one image. But I want to load multiple images from e folder and then to fade them in and out. But what I am interesting in, is how can I load all images from a folder without to repeat the code, as src="frames/frame_1" src="frames/frame_2" i want something soft as src="frames/frame_" + i + ".jpg" where i is the number of the frame
this is how I load only one image now
var img = new Image();
var div = document.getElementById('foo');
img.onload = function() {
div.appendChild(img);
};
img.src = 'frames/frame_1.jpg';
It's relatively simple. You basically put the code you already had in a loop:
var img, i,
imageCount = 5,
div = document.getElementById('foo');
for(i = 0; i < imageCount; i++){
img = new Image();
img.onload = function() {
div.appendChild(img);
};
img.src = 'frames/frame_' + i + '.jpg';
}
You can use a loop for :
var img,
div = document.getElementById('foo');
for (var i = 0, nbImg = 5; i < nbImg; i++) {
img = new Image();
img.onload = function() {
div.appendChild(img);
};
img.src = 'frames/frame_'+i+'.jpg';
}

Categories