I am trying to make 4 sliding galleries but I need to preload (cache) all images behind a splash screen before displaying the images in gallery form. I have been trying to use "jPreLoader v2 - http://www.inwebson.com/jquery/jpreloader-a-preloading-screen-to-preload-images" but with no luck.
The code below is how I have been trying to preload all images from each gallery directory on to a single gallery behind jpreloader then once load complete remove the whole gallery and display each gallery at a time.
var pictures = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
.......,
"30.jpg"
]
$(window).load(function(){
preLoad();
function preLoad(){
var max = 30;
var pic;
picture = '<table id="table" style="dipslay:table;"><tr>';
for (var i=0;i < max; i++){
if(i < 30){
pic = "images/art/"+pictures[i];
appendCell(pic);
}
if(i < 17){
pic = "images/street/"+pictures[i];
appendCell(pic);
}
if(i < 19){
pic = "images/doc/"+pictures[i];
appendCell(pic);
}
if(i < 16){
pic = "images/commercial/"+pictures[i];
appendCell(pic);
}
};
picture += '</tr></table>';
$('#imageScroller').append(picture);
}
function appendCell(pic){
picture +="<td class='image'><img class='i' src='"+pic+"'></td>";
return;
}
});
Im not quite sure how to implement the jpreloader on a dynamic image loading loop above instead of already inserted into the dom.
$(document).ready(function () {
$('body').jpreLoader();
});
Thanks.
Custom progress bar that updates as images are downloaded
var pictures = [
"1.jgp",
"2.jpg"
];
var loadedSoFar = 0;
function loaded( ) {
// do stuff
}
function updateProgress( ) {
loadedSoFar++;
var newWidth = $("#progress").width() * ( loadedSoFar / pictures.length );
$("#bar").stop( true, true );
$("#bar").animate({ width: newWidth }, 500, function( ) {
if( loadedSoFar === pictures.length ) { loaded() }
});
}
for( var i = 0; i < pictures.length; i++ ) {
var img = new Image();
img.src = pictures[ i ] + i;
img.onload = function( ) {
updateProgress();
}
}
Demo here
Related
I have the following code below, which successfully preloads images into the browser cache when the PreloadAllImages function is called. Does anyone know how to send a simple alert, e.g. "All images have been preloaded into the browser cache." when the last image (or all images) is loaded. I have 300 images, so setTimeOut won't work for latency/download lag reasons. I've tried callbacks, placing alert commands in different places, etc... but have not been successful.
This code is based on JavaScript Only Method #1 found here. https://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
function PreLoadAllImages() {
var images = new Array();
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
}
}
preload('Images/Image1.jpg', 'Images/Image2.jpg', ... , 'Images/Image300.jpg');
}
With some help, this is how the problem was solved in case anyone else needs it. Loaded images into an invisible div on the html page, then ran script to ensure everything was loaded. A button calls PreLoadAllImages() and then CheckImages().
var imagefiles = [
"Images/Image1.jpg",
"Images/Image2.jpg",
.....
"Images/Image300.jpg"];
function PreLoadAllImages () {
imagefiles.forEach(function(image){
var img = document.createElement('img');
img.src = image;
document.body.appendChild(img);});
$('img').hide();
}
var all_loaded;
function CheckImages() {
$('img').each(function(){ // selecting all image element on the page
var img = new Image($(this)); // creating image element
img.src = $(this).attr('src'); // pass src to image object
if(img.complete==false) {
all_loaded=false;
return false;
}
all_loaded=true;
return true;});
}
function CheckLoadingImages() {
var result;
var Checking=setInterval(function(){
result=CheckImages();
if(all_loaded==true) {
clearInterval(Checking);
MsgAfterLoading();
}
}, 2000);
}
function MsgAfterLoading() {
alert('All Images Loaded');
}
You could check if i is equals to the length of the array, so it will look like:
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
//the code
if (i == preload.arguments.length){
alert("Last image loaded");
}
//the code
}
Let me know if you have any questions.
Could you try looping through all the image elements and check the naturalWidth property, if they are all greater than 0 and its the last image then alert.
This link: Preloading Images in JavaScript (Need an Alert When Completed) should help
A promise might resolve your problem.
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise
var myPromise = new Promise( function(resolve, reject) {
// preload code
resolve(true);
};
myPromise.then(function() {
// your alert
};
You can use the onload event.
function PreLoadAllImages() {
var images = new Array();
var numberofimages = 0, loadedimages = 0;
function preload() {
numberofimages = preload.arguments.length;
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
images[i].onload = () => {
loadedimages++;
if(loadedimages == numberofimages){
alert("All images are loaded");
}
}
}
}
preload('Images/Image1.jpg', 'Images/Image2.jpg', ... , 'Images/Image300.jpg');
}
I have faced such a problem. I need to make a preloader with a percentage for a page but I don't know how. Actually, I don't need animation or simple preloader. What do I can and what do I have?
window.onload = function() {
var images = document.images,
imagesTotalCount = images.length,
imagesLoadedCount = 0,
preloader = document.getElementById('js_preloader'),
percDisplay = document.getElementById('js_preload__percentage');
for(var i = 0; i < imagesTotalCount; i++) {
image_clone = new Image();
image_clone.onload = image_loaded;
image_clone.onerror = image_loaded;
image_clone.src = images[i].src;
}
function image_loaded() {
imagesTotalCount++;
percDisplay.innerHTML = (((100 / imagesTotalCount) * imagesLoadedCount) << 0) + '%';
if(imagesLoadedCount >= imagesTotalCount) {
setTimeout(function() {
if(!preloader.classList.contains('done')) {
preloader.classList.add('done');
}
}, 1500);
}
}
};
This aproach allows to see all images to be downloaded and and calculate percentage. But how do I can also take in count the download of css and js files?
You could use the same approach, but with document.scripts and document.styleSheets collections.
I'm having a lot of trouble getting this slideshow to work. I have to make an external Javascript file. I am very confused because I don't know js very well at all. Any help will be appreciated.
var numImages = 3;
var images = [];
for (var i = 0; i < numImages; ++i) {
var image = new Image();
image.src = 'baby' + (i + 1) + '.jpg';
images.push(image);
}
var step = 0;
function slideit() {
if (! document.images) {
return;
}
document.images.slide.src = images[step].src;
step = (step + 1) % numImages;
}
setInterval(slideit, 2500);
Unless this somewhere in your HTML ...
<img id="slide">
Then this will be is undefined ...
document.images.slide
Therefore ...
document.images.slide.src = ...
Explains ...
Uncaught TypeError: Cannot set property 'src' of undefined
Here's a simplified piece of code that you can run and see it work
var images = [
'http://placehold.it/200?text=A',
'http://placehold.it/200?text=B',
'http://placehold.it/200?text=C'
]
function slideIt(elem, i, images) {
elem.src = images[i % images.length]
setTimeout(slideIt, 1000, elem, i+1, images)
}
slideIt(document.querySelector('#slideshow'), 0, images)
<img id="slideshow">
In your original code, you were preloading the images. I've made a small adaptation below to preload images first before initializing the slider.
var images = [
'http://placehold.it/200?text=A',
'http://placehold.it/200?text=B',
'http://placehold.it/200?text=C'
]
function slideIt(elem, i, images) {
elem.src = images[i % images.length].src
setTimeout(slideIt, 1000, elem, i+1, images)
}
function imagep(src) {
return new Promise(function(pass,fail) {
var i = new Image()
i.src = src
i.onload = function(event) { pass(i) }
})
}
Promise.all(images.map(imagep)).then(function(imgs) {
slideIt(document.querySelector('#slideshow'), 0, imgs)
})
<img id="slideshow">
I am currently working on SVG SMIL animation in which I am using some .png and .gif files for easing my animation in IE. For this animation I am trying to get Preloader before animation and its other contents get loaded.
Problem is I am not getting that Preloader working properly. My .html page is getting loaded first and then preloader is starting... In Preloader also, I have used several preloaders available on the web. But they are not helpful for me.
Script and .html files loading time can be counted by domContentLoaded but for images. I dont know how to do that. If someone can suggest me a way that would be great.
here is code of preloader.js, I found on web:
$(document).ready(function () {
"use strict"
//indexOf support for IE8 and below.
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt /*, from*/){
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++){
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
//bgImg for holding background images in the page & img array for images present in the document(<img src="">).
var bgImg = [], img = [], count=0, percentage = 0;
//Creating loader holder.
$('<div id="loaderMask"><span>0%</span></div>').css({
position:"fixed",
top:0,
bottom:0,
left:0,
right:0,
background:'#fff'
}).appendTo('body');
//Using jQuery filter method we parse all elemnts in the page and adds background image url & images src into respective arrays.
$('*').filter(function() {
var val = $(this).css('background-image').replace(/url\(/g,'').replace(/\)/,'').replace(/"/g,'');
var imgVal = $(this).not('image').attr('xlink:href');
//Getting urls of background images.
if(val !== 'none' && !/linear-gradient/g.test(val) && bgImg.indexOf(val) === -1){
bgImg.push(val)
}
//Getting src of images in the document.
if(imgVal !== undefined && img.indexOf(imgVal) === -1){
img.push(imgVal)
}
});
//Merging both bg image array & img src array
var imgArray = bgImg.concat(img);
console.log(imgArray.length);
//Adding events for all the images in the array.
$.each(imgArray, function(i,val){
//Attaching load event
$("<image />").attr("xlink:href", val).bind("load", function () {
console.log('val'+val);
completeImageLoading();
});
//Attaching error event
$("<image />").attr("xlink:href", val).bind("error", function () {
imgError(this);
});
})
//After each successful image load we will create percentage.
function completeImageLoading(){
count++;
percentage = Math.floor(count / imgArray.length * 100);
console.log('percentage:'+percentage);
$('#loaderMask').html('<span>'+percentage + '%'+'</span>');
//When percentage is 100 we will remove loader and display page.
if(percentage == 100){
$('#loaderMask').html('<span>100%</span>')
$('#loaderMask').fadeOut(function(){
$('#loaderMask').remove()
})
}
}
//Error handling - When image fails to load we will remove the mask & shows the page.
function imgError (arg) {
$('#loaderMask').html("Image failed to load.. Loader quitting..").delay(3000).fadeOut(1000, function(){
$('#loaderMask').remove();
})
}
});
A little trick I do to ensure my or external data or images are loaded before I start executing my js code is, I create a div with display:none and fill it with all the tags that I need loaded.
<body>
<span id="loadingText">Loading...</span>
<div style="display:none">
<img src="pathtoimage1">
<img src="pathtoimage2">
<img src="pathtoimage3">
</div>
<script>
window.onload = function(){
//This gets called when all the items in that div has been loaded and cached.
document.getElementById("loadingText").style.display = "none";
}
</script>
</body>
I use this for preloading images for animations.
you can add and remove how many you load as needed.
<script language="javascript">function preloader() {
if (document.images) {
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
var img4 = new Image();
var img5 = new Image();
var img6 = new Image();
var img7 = new Image();
var img8 = new Image();
var img9 = new Image();
img1.src = "image link here";
img2.src = "image link here";
img3.src = "image link here";
img4.src = "image link here";
img5.src = "image link here";
img6.src = "image link here";
img7.src = "image link here";
img8.src = "image link here";
img9.src = "image link here";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(preloader);</script>
I'm trying to create a hero (Reptile from MK) to move backwards, forwards, duck, etc... by key events. But when I try to iterate over certain amount of pictures to do the movement, it kinda bugs :S is there any other good approach? or what am I doing wrong?
All the movement is kinda bugged :/ is there a way to make it move smoothly? The pictures aren't working so good either, sometimes skips a few pictures or walks with the very same picture for over a few seconds.
Here's my code, I will add all in the same HTML:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<style>
#reptile_wrapper {
position:relative;
}
</style>
</head>
<body>
<div id="reptile_wrapper">
<img src="img/0.png"/>
</div>
<script>
/* Preload all the images and gifs */
var img_list, img_count, base_str, img_obj, i, prefix_str, suffix_img_str, suffix_gif_str;
img_list = [ 'd01', 'd02'];
gif_list = ['reptile_walk_forward', 'reptile_walk_backward', 'reptile_idle'];
prefix_str = 'img/';
suffix_img_str = '.png';
suffix_gif_str = '.gif';
img_count = img_list.length;
for ( i = 0; i < img_count; i++ ) {
base_str = img_list[ i ];
img_obj = new Image();
img_obj.src = prefix_str + base_str + suffix_img_str;
}
gif_count = gif_list.length;
for ( i = 0; i < gif_count; i++ ) {
base_str = gif_list[ i ];
img_obj = new Image();
img_obj.src = prefix_str + base_str + suffix_gif_str;
}
/* End of preloading images and gifs */
var duckImages = ["d01", "d02"];
var posx = 10;
reptileIdleAnimation();
$('body').keydown(function(event) {
switch(event.which) {
// D
case 68:
posx += 5;
$("#reptile_wrapper img").attr('src', 'img/reptile_walk_forward.gif')
.parent().css({left: posx+'px'});
break;
// A
case 65:
posx -= 5;
$("#reptile_wrapper img").attr('src', 'img/reptile_walk_backward.gif')
.parent().css({left: posx+'px'});
break;
// S
case 83:
$.each(duckImages, function( index, value ) {
var myAnim = setInterval(function(){
$("#reptile_wrapper img").attr('src', 'img/' + value + '.png')
.parent().css({"top": "40px"});
clearInterval(myAnim);
}, 200);
});
break;
default:
reptileIdleAnimation();
break;
}
})
.keyup(function() {
reptileIdleAnimation();
});
function reptileIdleAnimation() {
$("#reptile_wrapper img").attr('src', 'img/reptile_idle.gif');
}
</script>
</body>
</html>
Thanks.
The first thing I recommend is to preload all your images.
var img_list, img_count, base_str, img_obj, i, prefix_str, suffix_str;
img_list = [ 'one', 'two', 'three' ];
prefix_str = 'http://myserver.com/images/';
suffix_str = '.png';
img_count = img_list.length;
for ( i = 0; i < img_count; i++ ) {
base_str = img_list[ i ];
img_obj = new Image();
img_obj.src = prefix_str + base_str + suffix_str;
}
Of course you will need to replace the img_list, prefix_str, and suffix_str with your own values. Once the images are preloaded, any network latency would be removed, and your animation should be smoother. Let me know if that isn't enough :)