I have a big problem with images in javascript embedded aplications. I want make a preload image but I don't know how the browser works.
See this simple example: code
var colors = [
"http://www.robolaranja.com.br/wp-content/uploads/2014/10/Primeira-imagem-do-filme-de-Angry-Birds-%C3%A9-revelada-2.jpg",
"http://imguol.com/c/noticias/2013/12/13/13dez2013---esta-imagem-mostra-a-nebulosa-de-caranguejo-um-iconico-remanescente-de-supernova-na-nossa-galaxia-vista-do-observatorio-espacial-herschel-e-do-telescopio-hubble-uma-nuvem-de-gas-e-poeira-1386961235961_956x500.jpg",
"http://wallpaper.ultradownloads.com.br/121350_Papel-de-Parede-Imagem-Abstrata_1920x1200.jpg"
]
var currentDiv = "div2";
var count = 0;
var lenght = colors.length;
var timeForNextImage = 0;
var preloadOk = false;
setInterval(function() {
count ++;
if (count > lenght) count = 0;
var date = new Date();
var time = date.getTime();
if (time > (timeForNextImage - 3000) && preloadOk == false) {
preLoad();
} else if (time > timeForNextImage) {
play();
}
}, 300);
var play = function() {
if (currentDiv == "div2") {
$('#'+currentDiv).css("visibility", "visible");
} else {
$('#div2').css("visibility", "hidden");
}
var date = new Date();
timeForNextImage = date.getTime() + 10000;
preloadOk = false;
$("#lbl").text("div atual: "+currentDiv);
};
var preLoad = function() {
if (currentDiv == "div1") {
currentDiv = "div2";
} else {
currentDiv = "div1";
}
$("#" + currentDiv).css("background-image", 'url('+colors[count]+')');
preloadOk = true;
};
How you can look, I do a preload, in theory.. but, the browser only processes my image when I put it in the stage ?
What if I change the z-index attribute, it renders again?
You return preloadOK = true but the image doesn't load. That's not a preloader.
To make a preloader you can play with new Image() object or with load() event.
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(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
)
See more
3 Ways to Preload Images with CSS, JavaScript, or Ajax
A simple way to preload an image is to just create an image tag and set the url as the src. You don't have to attach it to the DOM to make the request.
var preLoad = function() {
var img = new Image();
img.src = colors[count];
};
Related
I have a javascript which uses many images, and I want to load them all before the user starts clicking around. The images are a little bit big, so it takes a while. Here's my code:
startTest();
function preloadImages() {
console.log("preload images");
for(var i = 1; i <= 132; i++) {
var img = new Image();
images[i-1] = "images/"+i+".png";
img.src = images[i-1];
if(i == 132) {
img.load = doneLoading();
}
}
}
function doneLoading() {
console.log("done loading");
document.getElementById("laading").style.display = "none";
console.log("loading gone");
showReady();
}
function startTest() {
console.log("start test");
trialCount = 0;
document.getElementById("laading").style.display = "block";
preloadImages();
var hammertime = Hammer(document.body).on("touch", function(event) {
registerTouch(event);
});
startTestTime = +new Date();
console.log("end start test");
}
As you can see, startTest() is first called, which calls preload images. Here's the issue:
When I load the page in the browser, the javascript console indicates that "done loading" has been printed, however the spinny wheel on the tab in the browser shows that the webpage is still loading...
What's going on here? How can I figure out once all my images are done loading?
You need to check on each image load that the image is the last one to load. Check using a count variable (loaded).
function preloadImages() {
var loaded = 0;
for(var i = 0; i <= 132; i++) {
var img = new Image();
images.push("images/"+(i+1)+".png");
img.src = images[i];
img.onload = function(){
loaded++;
if(!(loaded < 132)){
// all images have loaded
doneLoading();
}
}
}
}
In order to do a pre-loading, you will have to keep checking the complete status for each image that is being downloaded. Since, you can't know beforehand how much time it will take for each image to download (depending on latency or size), you will have to implement a timer which will keep polling the complete status on each image.
Here is one possible algorithm:
var timer = null,
numImages = 132,
allImages = new Array;
function preLoadImages() {
document.getElementById('loadcaption').innerHTML = 'Loading images... ';
for (var i = 0; i < numImages; i++) {
var tmp = "images/" + i + ".png";
allImages[i] = new Image();
allImages[i].onLoad = imgOnLoad(tmp);
allImages[i].src = tmp;
}
timer = window.setInterval('checkLoadComplete()', 250);
}
function imgOnLoad(imgName) { window.status = 'Loading image... ' + imgName; }
function checkLoadComplete() {
for (var i = 0; i < allImages.length; i++) {
if (!allImages[i].complete) {
imgOnLoad(allImages[i].src);
document.getElementById('loadcaption').innerHTML = 'Loading images... ' + Math.round((i/allImages.length)*100,0) + ' %';
return;
}
}
window.clearInterval(timer);
document.getElementById('loadcaption').innerHTML = 'Completed.';
window.status = '';
}
Where loadcaption is a simple HTML element to show progress. (You can also use an animated gif for loading animation).
The idea is to keep checking the complete status on each image by calling checkLoadComplete by a timer. Once all images are (load) complete, the for loop exits and the timer is cleared.
You start the pre-loading process by calling preLoadImages(); function.
I have a function written in javascript that allows me to scroll through an array of images iterated at a certain interval, now I would like to add some more functionality to it by pausing the rotation when I hover over any of the images in the array.
Javascript
(function() {
var rotator = document.getElementById('bigImage');
var imageDir = '../images/headers/';
var delayInSeconds = 5;
var images = ['ImageOne.png', 'ImageTwo.png', 'ImageThree.png', 'ImageFour.png',
'ImageFive.png',
'ImageSix.png'];
var num = 0;
var changeImage = function() {
var len = images.length;
bigImage.src = imageDir + images[num++];
if (num == len) {
num = 0;
}
};
setInterval(changeImage, delayInSeconds * 1000);
})();
You could store the id returned from setInterval, and pass it to clearInterval when the image is hovered over.
So, on mouse over, you clear, and on mouse out you set it going again.
Hope that helps!
Use jQuery:
var rotationRunning = true;
var changeImage = function() {
if (rotationRunning) {
var len = images.length;
rotator.src = imageDir + images[num++];
if (num == len)
num = 0;
}
}
};
$(rotator).hover(
function() { rotationRunning = false; },
function() { rotationRunning = true; }
);
I have a set of images that are frames in an animation like: frame-1.jpg, frame-2.jpg and I have about 400 images.
What I want to do is preload these 400 images before the animation starts.
Usually when preloading images I use the following:
var images = [
'img/nav-one-selected.png',
'img/nav-two-selected.png',
'img/nav-three-selected.png',
'img/nav-four-selected.png'
];
$(images).each(function() {
var image = $('<img />').attr('src', this);
});
But in this instance, listing the images in the var isn't feasible, and I also wish to fire off the start animation once the images have all been loaded.
So far I have the following:
$spinner_currentFrame = 1;
$numFrames = 400;
function preloadImages() {
$($images).each(function() {
var image = $('<img />').attr('src', this);
});
startAnimation();
}
function startAnimation() {
$spinner_loadingAnim = setInterval(function () {
UpdateSpinner();
}, 140);
}
function UpdateSpinner() {
$spinner_currentFrame = $spinner_currentFrame + 1;
if($spinner_currentFrame > $numFrames) {
$spinner_currentFrame = 1;
}
console.log($spinner_currentFrame);
$('#spinner').css("background-image", "url(frame-" + $spinner_currentFrame + ".jpg)");
}
$(document).ready(function() {
preloadImages();
});
So the plan is that I preload images that are from 1 to 400 and then once that's completed then start the animation. How would I build the $images var though?
I've thought about something like:
$images = [];
$frame = 1;
$numFrames = 400;
$($frame).each(function() {
$frame = $frame + 1;
if($frame <= $numFrames) {
$images =+ 'frame-' + $frame + '.jpg';
}
});
But I'm not sure how a) efficient this is and b) how to do the callback once all images have loaded successfully.
You should use a standard javascript for loop instead of the jQuery's foreach. Foreach is wonderful for looping over an array or set of objects, but not in this case. Here is an example, please note that you have to bind the onload event handler before you set the Image object's src property.
UPDATE: added more functions to complete the entire example.
var loaded_images = 0;
var frames = 400;
var images = [];
function preloadImages() {
for (i=0; i < frames; i++) {
images[i] = new Image();
images[i].onload = function() {
loaded_images += 1;
checkLoadingFinished();
}
images[i].src = 'frame-' + i + '.jpg';
}
}
function checkLoadingFinished() {
if (loaded_images >= frames) {
startAnimation();
}
}
function startAnimation() {
var frameNumber = 0;
var timer = setInterval(function() {
$('#img-dom-element').attr('src', images[frameNumber]);
if (frameNumber > frames) {
frameNumber = 0;
else
frameNumber++;
}, (1000/30)); // (1000/30) = 30 frames per second
}
$(document).ready(function() {
preloadImages();
});
I dont know if it fits to your special case but I use
http://thinkpixellab.com/pxloader/
to preload images. You can add the paths and get one callback if all images are loaded. Afterwards you can start animation.
My application is a MVC, using MS SQL to get the image file names. I am using the following script to preload images; would like to know How I can display hourglass cursor while waiting to complete the preload.
function preload_images() {
var i, count = 0;
$('#selector').css('cursor', 'wait');
for (i = 1; i < sl; i++) {
images[i] = new Image();
images[i].onload = images[i].onerror = function () {
count++;
if (count == sl) {
$('#selector').css('cursor', 'default');
}
}
images[i].src = impath.toString() + im.toString() + i + ".jpg";
}
}
It works great first time, however, when I change the file name from a dropdownlist, the hourglass does not stop even all images are load. Thanks in advance.
From the code above you are loading sl-1 images, but the condition to stop the wait cursor is sl images(if (count == sl)), so change it to if (count == (sl-1))
Thanks to Musa for providing the initial solution, here is the way I got it to work, just in case someone is looking for it:
var images = [];
function preload_images() {
showLoadingImage();
$('#selector').css('cursor', 'wait');
for (i = tochar; i < sl; i++) {
images[i] = new Image();
var name = impath.toString() + imStart.toString() + i + ext;
images[i].src = 'ImageHandler.ashx?img=' + name + '&window=50&level=50 &slice=0';
if (i == sl - 1) {
images[i].onload = images[i].onerror = function () {
$('#selector').css('cursor', 'Default');
hideLoadingImage(this);
};
}
}
}
function showLoadingImage() {
$('#imagediv').append('<div id="imagediv1"><img src="../Content/images/ajax-loader2.gif" alt="Loading..." /></div>');
$('#imagediv1').show();
}
function hideLoadingImage(img) {
$('#imagediv1').hide();
img.onload = img.onerror = null;
}
i would like to make image slideshow.
First, i would have just thumbnails and when clicked on the one, it would pop up overlay(some sort of div, or something) and there would be option to move through the images. I don't want to use anykind of libraries
i have this, so far:
NewImg = new Array (
"img/1gif",
"img/2gif",
"img/3gif"
);
var ImgNum = 0;
var ImgLength = NewImg.length - 1;
var delay = 3000;
var lock = false;
var run;
function chgImg(direction) {
if (document.images) {
ImgNum = ImgNum + direction;
if (ImgNum > ImgLength) {
ImgNum = 0;
}
if (ImgNum < 0) {
ImgNum = ImgLength;
}
document.slideshow.src = NewImg[ImgNum];
}
}
function auto() {
if (lock == true) {
lock = false;
window.clearInterval(run);
}
else if (lock == false) {
lock = true;
run = setInterval("chgImg(1)", delay);
}
html part
Previous
Auto/Stop
Next
this is the regular image gallery. With regular sized images.
I don't know how to implement those thumbnails
thank for helping me around here
i forgot, i have
used following code for overlays(but don't know how to implement it here)
function toggleLayer( whichLayer )
{
var elem, vis;
if( document.getElementById )
{
elem = document.getElementById( whichLayer );
}
vis = elem.style;
if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
vis.display = (vis.display==''||vis.display=='block')?'none':'block';
}
http://jsfiddle.net/sevdah/z7Ggx/1/ on jsfiddle, but it is not working, don't know why