Javascript: preload next image - javascript

not very big on JS.
I currently have a script I use to load/change background images every xxx seconds.
What I would like is to display an image and preload the next one so it displays seamlessly (ie: no jittering or slow loads).
Here is my current script, can this be adapted to achieve such a result?
<!-- Background Image Changer inpired by: https://stackoverflow.com/a/7265145 -->
var images = ['images/image01.jpg',
'images/image02.jpg',
'images/image03.jpg',
'images/image04.jpg',
'images/image05.jpg',
'images/image06.jpg',
'images/image07.jpg',
'images/image08.jpg',
'images/image09.jpg',
'images/image10.jpg',
'images/image11.jpg',
'images/image12.jpg',
'images/image13.jpg',
'images/image14.jpg',
'images/image15.jpg',
'images/image16.jpg',];
var numSeconds = 30;
var curImage = 0;
function switchImage()
{
curImage = (curImage + 1) % images.length
document.body.style.backgroundImage = 'url(' + images[curImage] + ')'
}
window.setInterval(switchImage, numSeconds * 1000);
NOTES: There are 50 images in my script. I've only used fake named placeholders for clarity.
EDIT: To be clear, I only want one image displayed and the next (one) image to be preloaded. It's running on a RPi 3b so not much memory is available.

I want to add a different answer here. There are a few options you can use to improve your web page performance. Using <link> with preconnect and preload rel value can helps you to load resources before using them:
Use preconnect keyword for the rel attribute to tell the browsers that the user is likely to need resources from this origin and therefore it can improve the user experience by preemptively initiating a connection to that origin.
<link rel="preconnect" href="<your-images-base-url">
Use preload keyword for the rel attribute to declare fetch requests in the HTML's , specifying resources that your page will need very soon. This ensures they are available earlier and are less likely to block the page's render, improving performance. Taken from https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
Create preload link:
const preloadLink = document.createElement('link');
document.head.appendChild(preloadLink);
preloadLink.rel = 'preload';
preloadLink.as = 'image';
function preloadNextImage(href) {
preloadLink.href = href;
}
function switchImage()
{
curImage = (curImage + 1) % images.length
document.body.style.backgroundImage = 'url(' + images[curImage] + ')';
preloadNextImage(/* <next-image-url> */)
}

You could just load the next image when displaying the current one using the JavaScript Image object. When switchImages runs again then the image will be already in the browsers cache. Also, the cached images are stored in a new array, so the cache "generator" will be ran only once. With this snippet you will need enough delay between iterations, so the next image will have enough time to be downloaded from the sever.
var images = ['images/image01.jpg',
'images/image02.jpg',
'images/image03.jpg',
'images/image04.jpg',
'images/image05.jpg',
'images/image06.jpg',
'images/image07.jpg',
'images/image08.jpg',
'images/image09.jpg',
'images/image10.jpg',
'images/image11.jpg',
'images/image12.jpg',
'images/image13.jpg',
'images/image14.jpg',
'images/image15.jpg',
'images/image16.jpg',];
var numSeconds = 2;
var curImage = 0;
var cache = [];
function switchImage()
{
curImage = (curImage + 1) % images.length;
document.body.style.backgroundImage = 'url(' + images[curImage] + ')';
if(images[curImage + 1] && !cache[curImage + 1]) {
cache[curImage + 1] = new Image();
cache[curImage + 1].src = images[curImage + 1];
}
}
window.setInterval(switchImage, numSeconds * 1000);

Related

ajax undefined after a thousand iterations

When creating an animation I try to use javascript for additional effects, namely snow being piled up and falling off the edges of the foreground. I figured that the javascript could do the "calculations" on a <canvas> that had the image, then send the "snow" to a php script that would create the png images. This is all placed on my local "server" because that is the only one that can write files.
<html>
<head>
<title>Making Snow</title>
</head>
<body bgcolor="black">
<canvas id="canvas" width="1920px" height="1080px"></canvas>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var canvas;
var ctx;
var frame=-530;
var simg = new Image()
var dimg = new Image()
onload = function()
{
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
simg.src = "prodB/C/DGB.0530.png"
}
simg.onload = function()
{
var ipo=3;
// Initialize all pixels on the screen/page
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(simg,0,0);
document.title = "Making Snow " + (frame+530) + " / 7000";
snowdraw();
}
dimg.onerror = function()
{
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
}
dimg.onload = function()
{
frame++;
if(frame<530)
simg.src = "prodB/C/DGB.0530.png"
else if(frame>4400)
simg.src = "prodB/C/DGB.4400.png"
else
simg.src = "prodB/C/DGB." + zeroFill(frame,4) + ".png"
}
var snowdraw = function()
{
var temp;
var canvasData = "";
// console.log(screen);
// Animation
// Choose a random pixel at the top of the screen
if(frame<7000)
{
for(ny=canvas.height-2; ny>=0; ny--)
{ // Iterate through all the pixels starting from the bottom right corner.
for(nx=canvas.width-2; nx>=0; nx--)
{
canvasData=canvasData+"1";
}
}
$.ajax({
method: "POST",
url: "makesnow.php",
data:{ imgData: canvasData, frame: (frame+530) }
})
.done(function( msg ) {
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
});
}
else
{
document.title = "COMPLETE";
}
}
// http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript
// by Peter Bailey http://stackoverflow.com/users/8815
function zeroFill( number, width )
{
width -= number.toString().length;
if ( width > 0 )
{
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
</script>
</html>
However, on the 1640th frame (or more precisely frame=1110) ajax is suddenly undefined. The image snow1640.png is created, but the browser tells me ajax is not defined and won't advance passed Making Snow 1640 / 7000. Because of the small random nature for each "snow flake" I can't just pick it up from where I left off, as the snow would jump from one frame to the next. Though I did try that at one point and ajax still stopped after that frame.
I first ran it on the local machine running Firefox (http://127.0.0.1/...) then moved onto another machine on the network which is more powerful running Chrome and both died on that same frame. Thought it might be a memory or file limit so I moved the complete frames out of there. Still nothing.
EDIT: Code now snippit of just the problem.
Also, console.log for data and ajax.responseText seem to be generally empty, both during successful "renders" and when it starts iterating ajax is not defined (every other line empty, every other error).
EDIT: New development! Turns out that the error ReferenceError: ajax is not defined anyways gets called between frames (and the 404 when asking dimg if image was created).
EDIT: By typing in console.log($.ajax) after onload and commenting out simg.src I got function ajax().
Error persists, this time I expanded it to reveal the following:
success http://127.0.0.1/ag/makesnowBC.html 197:7
j http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27131
fireWith http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27949
x http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:22242
b http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:26298
EDIT: Changed the code to now use Synchronous ajax. This time there are no error messages what so ever, but it still stops at 1640.

Javascript Slide show

I have a simple fading slide-show which works great for a while, but runs to about 300 images. After a while it starts jumping and missing some, which I assume is down to too many images being loaded. Is there a way of 'unloading' images once viewed, or is it likely to be something else?
Let all images load before you display the slide show, or skip not loaded images.
You could do this like this for example:
var images = ['./path1.jpg', './path2.jpg']; // Array with all images
var imageCount, imagesLoaded, c;
imageCount = images.length; // Get images count
imagesLoaded = 0;
for (c = 0; c < imageCount ; c++){ // Loop thorough all images
var image = document.createElement('img'); // Create img tag
image.setAttribute('src', images[c]); // Set src attribute
document.body.appendChild(image); // Add img tag to body
image.onload = function() {
imagesLoaded++; // Add loaded image to loaded images count
console.log('Loaded: ' + imagesLoaded + '/' + imageCount); // debug
if (imagesLoaded == imageCount){ // when all images loaded
// Start your slideshow
}
}
}

How to get JavaScript to rotate through a series if images

I'm having an issues where I cannot get my code to rotate multiple images in a cycle for my image gallery (just a bunch of images i got on google). I can however to get 1 image to cycle through the images but everything iv tried to get it to work with more than one has failed. Any help/ tips would be useful. Im in college for web development and i understand the basics of javascript it just seems when it comes to creating applications i have a bit of trouble.
Here is a link to my code: jsFiddle
$(document).ready(function () {
var img = document.images;
// Holds the image collection
var counter = 0;
var imgArray = [];
imgArray[0] = "http://www.zeroprox.tk/temp/images/img1.png";
imgArray[1] = "http://www.zeroprox.tk/temp/images/img2.jpg";
imgArray[2] = "http://www.zeroprox.tk/temp/images/img3.png";
imgArray[3] = "http://www.zeroprox.tk/temp/images/img4.jpg";
imgArray[4] = "http://www.zeroprox.tk/temp/images/img5.jpg";
imgArray[5] = "http://www.zeroprox.tk/temp/images/img6.png";
imgArray[6] = "http://www.zeroprox.tk/temp/images/img7.jpg";
imgArray[7] = "http://www.zeroprox.tk/temp/images/img8.png";
$("#left-arrow").click(function () {
if (counter < 0) {
counter = imgArray[counter] - 1;
} else {
counter--;
}
img[1].src = imgArray[counter];
});
// Left arrow... Previous
$("#right-arrow").click(function () {
counter = (counter + 1) % imgArray.length;
img[1].src = imgArray[counter];
});
// right arrow... Next
});
JSFiddle
Check this, it should solve your problem ;)
You were replacing every time the same image, now creates a new one and remove another.
Also added div#imagelist to use as a image container and access easier from JavaScript
var newImg = $(document.createElement("img"));
newImg.attr("src",imgArray[counter]);
$("#imagelist img").last().remove();
$("#imagelist").prepend(newImg);

Random image load

so I already have a image randomiser, but i am now looking to extend this so that IF image 1 was loaded last, load image 2 and so on.
$(document).ready(function () {
var images = ['imageTest.jpg', 'imageTest2.jpg', 'imageTest3.jpg', 'imageTest4.jpg'];
$('.mainHero-fluid').css({
'background-image': 'url(/assets/images/' + images[Math.floor(Math.random() * images.length)] + ')',
});
});
how can I do this?
I guess somthing like that should do it. You can gain the current Image from the source attribute of the imageā€¦
//copy the whole list
var newImages = [].concat(images), newImage;
//remove the current image
newImages.splice(images.indexOf(<currentImage>),1);
//get a random entry
newImage = newImages[Math.round(Math.random() * (newImages.length - 1))];
Good luck!

Image preloading with array

I am using the following code to preload images in an image gallery:
$(window).bind('load', function(){
var imageNumber = $(".image").attr("alt");
var imageUp = parseInt(imageNumber) + 1
var imageUp2 = parseInt(imageNumber) + 2
var imageDown = parseInt(imageNumber) - 1
var preload = [
'image' + imageUp + '.jpg',
'image' + imageUp2 + '.jpg',
'image' + imageDown + '.jpg',
];
$(document.createElement('img')).bind('load', function(){
if(preload[0]) this.src = preload.shift();
}).trigger('load');
});
I modified another basic javascript/jQuery preload script, adding variables in order to get a numeric value from the current image's alt-tag and preload images that are immediately before and after it (n+1 n+2 n-1) in the gallery. This works, though I imagine it may be kind of ugly.
What I want to do is add or call another array containing all images in the directory, so that after the previous and next images have loaded, the current page continues to preload other images, saving them in the browsers catche for future viewing as the user moves through the gallery.
Ideally, this second array would be called from an external .js file, so as to prevent having to update every page individually. (Or maybe it would be easier to save the entire script in a external .js file for each directory and fill out the rest of the array based on that directory's contents?).
Web design is only a hobby for me (I'm a photographer), so my knowledge of javascript is limited--just enough to customize pre-built functions and collage scraps of code.
I would really appreciate if someone could point me in the right direction on how to modify my code.
Thanks in advance,
Thom
I have never used a jQuery preload script but i have done a lot of preloading with 'vanilla' javascript.
Try the code i have added below, it may solve your problem.
function preLoad() { // my preload function;
var imgs = arguments, imageFolder = [];
for (var i = 0; i < imgs.length; i += 1) {
imageFolder[i] = new Image();
imageFolder[i].src = imgs[i];
}
}
var gallary = []; // all gallary images
$(window).bind('load', function(){
var imageNumber = $(".image").attr("alt");
var imageUp = parseInt(imageNumber) + 1
var imageUp2 = parseInt(imageNumber) + 2
var imageDown = parseInt(imageNumber) - 1
var preload = [
'image' + imageUp + '.jpg',
'image' + imageUp2 + '.jpg',
'image' + imageDown + '.jpg',
];
$(document.createElement('img')).bind('load', function(){
if(preload[0]) this.src = preload.shift();
}).trigger('load');
preLoad(gallary); // preload the whole gallary
});
EDIT
preLoad() : this function accepts image urls as arguments e.g preLoad('image_one.jpg', 'image_two.jpg','image_thre.jpg');
The preLoad function has two variables var imgs and var imageFolder, imgs stores all the image urls and imageFolder stores image Objects, that is, preload loaded images.

Categories

Resources