I'm currently making a little game where every few seconds some images are removed and reloaded to update their new status and position, which is done with the code below. However, this causes these images to flicker at every reload which is especially annoying when an image is on the exact same spot and can actually cause a miss-click now and then. Is there any way I can prevent my images from flickering?
$(".armysprite").remove();
for (var i = 0; i < armies.length; i++) {
iniArmies(i); // Function that adds the new army images back into the DOM
}
The easiest way is to do it is: to load new image in hidden div, and on the function of onload of the image to show this div and hide your old div (like css property: display:none; / display:block;)
Related
I have been using $().hide and $().show to make a smooth transition between images in a slideshow-like fashion. For example, when the right arrow key is pressed, the current image being displayed will slide to the left and disappear, the image will change, and it will slide into view from the right. This is the code I use for such a transition:
$('#mainImage').hide("slide", { direction: "left" }, 200);
$('#mainImage').show("slide", { direction: "right" }, 700);
setTimeout(function() { changeImg(pageNumberNew); }, 200);
The setTimeout() function is purely to control when in the transition the image source will change. The pageNumberNew variable is the URL of the image to be changed to. Here is the changeImg() function:
function changeImg(number) {
document.getElementById('mainImage').setAttribute('src', "/largefiles/2021roadatlas/Images/" + number + ".jpeg");
curPageNumber = number;
setWidth();
}
However, on the first transition of images, it will become very choppy, because the images haven't been loaded yet. I have tried various methods of preloading images, such as
Preloading images with JavaScript
Preloading images with jQuery
Waiting for image to load in JavaScript
JavaScript waiting until an image is fully loaded before continuing script
But none of these have worked.
Once an image has been loaded for the first time, navigating back to that image will be smooth. I would like a solution where these images can be preloaded before the user starts interacting, possibly loading each image before the transitions take place - causing for a slight delay in starting the animation, but allowing it to be smooth.
You can see what I have so far in action here, if you type in 13 and use the right and left arrow keys. The animations might not be choppy if you use desktop, try that website on mobile to see the issue.
TO BE CLEAR: I want a way to preload images in JavaScript, but I haven't been able to use the normal methods of preloading images, as described above.
The reason it is loading so slow is the large image. You should make the image size of the original photo smaller. I can see that the original size is around 5000 x 6500 and you are scaling it down to around 1000 x 600. The original image is unnecessarily big which causes the slow load.
I am trying to find a more modern solution that doesn't use jQuery as I am using React (Gatsbyjs specifically).
I have a website with multiple image carousels that contain high res images.
The issue is the each image carousel only show one image at a time, so only when the user navigates to the next image does the image get fetched, this results in a choppy loading appearance.
I have tried researching online with onLoad and load event listeners but none seem to have worked so far because they only load the image that is currently being shown by the carousel, instead of all of the images in the carousel.
If there is a way to first load all the images, then set the state to true, and only after the state is true, then the rest of the DOM appears onto the screen, that would be perfect.
Any suggestions? Thanks.
Website in question: https://dev--yachtgamechanger.netlify.com/
As Lonnie Best said, I ended up using Promise.all() to capture the loads of the images.
Just in case anyone else want to check it out:
https://codesandbox.io/s/react-image-preload-ptosn
I guess that your lib is using lazy load approach. And it's really good when dueling with high res images.
You still can change the approach to load all the images before rendering the UI, by going into the carousel component, change the rendering behavior by checking whether all images be loaded or not before render.
Updated: Because you are using gatsby-image, so just use this property:
loading: "eager". For EX:
<Img
fixed={data.file.childImageSharp.fixed}
alt="Gatsby Docs are awesome"
loading="eager"
/>
https://www.gatsbyjs.org/packages/gatsby-image/
You can ensure that an image is pre-downloaded 100% well before it gets displayed to the screen.
Simply create an Image element and set its src property to the URL where the image is located. Then use the image's onload event to detect when it is ready for instant display.
// Image to Pre-Download:
var image = new Image();
console.time("Image Fully Downloaded in");
image.src = "https://www.nasa.gov/sites/default/files/thumbnails/image/pia24870.jpeg";
image.onload = function()
{
console.timeEnd("Image Fully Downloaded in");
console.log("Image is ready for viewing.");
clearInterval(interval);
progress.parentNode.replaceChild(btn, progress);
}
// Fake Progress Indicator:
let progress = document.createElement("progress");
progress.value = 3;
progress.max = 100;
progress.textContent = "Fake Progress";
document.body.appendChild(progress);
let interval = setInterval(()=>
{
if (progress.value === 99)
{
progress.value = 0;
}
else
{
progress.value = progress.value + 1;
}
},50)
// Button to Replace Progress Indicator:
let btn = document.createElement("button");
btn.textContent = "View Entire Image Instantly";
btn.addEventListener('click',function()
{
this.parentNode.replaceChild(image, this);
});
img { max-width: 100%; }
<p>Only after the image is completely downloaded, will you see the button to view it:</p>
Based on this concept, you could pre-load/queue as many images as you like into image objects, so that they are ready to be displayed instantly (well before the user decides to view the next image). Here's an example where I'm switching between preloaded images automatically (so fast that it looks like an animated gif -- but it is actually 27 separate images from 27 different URL locations): See statue example and view source.
How can you cancel the loading of an image defined by a background-image attribute?
There a few questions that show how to cancel the loading of an <img> tag by setting the src to '' or to a different image (such as this one, answered by Luca Fagioli). But this does not work for background images.
Luca provided a jsfiddle ( jsfiddle.net/nw34gLgt/ ) to demonstrate the <img src="" /> approach to canceling an image load.
But modifying that jsfiddle to use background-image instead clearly shows that the image continues loading, even if:
you do background-image: none (as suggested here)
or background-image: url("web.site/other_image.jpg")
or background-image: url('').
In fact, in my testing on Firefox 54, the background image continues loading even if you do window.stop() or close the tab.
So, is there any way at all to stop loading a background image once it starts?
My use-case for this is client-side, so I can't change the site to not use background images. I am viewing a gallery of many thumbnail images, but the thumbnails are much larger than they need to be. Smaller versions are available so I wanted to replace the large thumbnails with the smaller versions via Greasemonkey to ease the network load on my poor, slow connection. Each entry in the gallery is a <div> with a background-image inside an <a> linking to the full-size image. (using Fotorama).
If you need to target inline styles on the elements, then I think you can run a script near the bottom of the page to do that.
Testing this locally, the original images do not show as loading in the network tab.
var allDivs = document.getElementsByTagName('DIV');
for (var i = 0; i < allDivs.length; i++) {
// check for inline style
var inlineStyle = allDivs[i].getAttribute('style');
// check if background-image is applied inline
if (inlineStyle && inlineStyle.indexOf('background-image') != 1 ) {
allDivs[i].style.backgroundImage = 'url("newImg.jpg")'; // assign new value?
}
}
That is going to grab every div, so hopefully these elements have a class you can use to query first. Then you have a smaller collection to run the above on.
Classes, not inline styles:
If you could target classes, it would look a bit cleaner. You could create a new class and use it.
var els = document.querySelectorAll('.bg-img');
for (var i = 0; i < els.length; i++) {
els[i].classList.remove('bg-img');
els[i].classList.add('no-bg-img');
}
I have a few img tags whose src is changed onmouseover. This takes an inordinate amount of time to load. How can I improve the load time? The images are basically just different icons.
You can do a few things.
1) CSS Sprites is probably the preferred method.
2) You can load the images in a div and set that div to display none, making it so the images are already loaded so on mouseover they'll be there instantly.
Also here's a link on how to PreLoad images with CSS
There are a few ways to do it, the ideal solution in your case would be to use CSS sprites considering they're icons. However, depending on the situation sometimes sprites aren't ideal.
Here's one solution using JavaScript to preload images:
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://image-1.jpg',
'http://image-2.jpg',
'http://image-3.jpg'
);
What you're trying to do is achieve a rollover. It is strange that you'd experience a very long delay in this process. Usually, if the images aren't stored in some remote location, they're pretty fast.
Look at this article for some guidance
Other things you could try:
- sprites in css
- you could use two overlapping divs and hide one and unhide the other and vice versa
Is it possible to load a background-image asynchronously?
I've seen many jQuery plugins to load normal image in an asynchronous way, but I can't find if it's possible to preload / asynchronously load a background-image.
EDIT
I clarify my problem. I've been working on this test site http://mentalfaps.com/
The background image is loaded randomly from a set of images refreshed each hour by a chron job (which takes random images on a flickr catalog).
The host is free and slow at the moment, so the background image takes some time to load.
The positioning of the first overlay (the one with the PNG transparent mentalfaps logo) and width are regulated by a function created in the jQuery(document).ready construct.
If you try to refresh the page many times, the width of the right overlay div is 0 (and so you see a "hole" in the layout)
Here is the method to set my positions:
function setPositions(){
var oH = $('#overlay-header');
var overlayHeaderOffset = oH.offset();
var overlayRightWidth = $(window).width() - (overlayHeaderOffset.left + oH.width());
if (overlayRightWidth >= 0) {
$('#overlay-right').width(overlayRightWidth);
} else {
$('#overlay-right').width(0);
}
var lW = $('#loader-wrapper');
lW.offset({
left: (overlayHeaderOffset.left + oH.width() - lW.width())
});
}
The problem is that the $(window).width() is lower then the effective window width! so the check fails and the script goes for $('#overlay-right').width(0);
any ideas?
Not sure whether I really understand your question, but background images (and all other images) are already loaded asynchronously - the browser will start separate requests for them as soon as it encounters the URL while parsing the HTML.
See this excellent answer for background on loading order: Load and execution sequence of a web page?
If you meant something else, please clarify.
The trick to loading something in the background is to load it once, so the next time when it is loaded it already is in the cache.
Put the following at the end of your html:
<script>
var img = new Image();
img.onload = function () {
document.getElementsByTagName('body')[0].style.backgroundImage = 'background.png';
};
img.src = 'background.png';
</script>
You could use a prefetch link in the head.
<link rel="prefetch" href="/images/background.jpg">
You should be able to add these links to the head via JavaScript.
I like to use CSS to fill the background with a color for page load.
After DOM ready event, I use jQuery to modify the CSS and add a background image. That way, the image isn't loaded until after page loads. Not sure about async, but this method gives the user a decent experience.
Example: http://it.highpoint.edu/
The right side navigation links have a background image. The page initializes with a background color. It is replaced with a background image after page load, via jQuery.
changes in this file jquery.ImageOverlay.js
set your height and width and enjoy this...
imageContainer.css({
width : "299px",
height : "138px",
borderColor : hrefOpts.border_color
});
As it is already mentioned, the background image is loaded asynchronously. If you need to load the background image from JQuery code you may also set the addClass() method to set a CSS class or attr("style=\"background-image:url('myimage.png')\"")
Ive found the answer myself, it was a problem due to the .offset() method that gived sometimes the wrong values.
I had the write values using the .position() :
var overlayHeaderOffset = oH.position();