I am having a problem with a site. My problem is I am loading several images progressively - starting with a small resolution image for fast loading I am then ajaxing a bigger image in (normally the original size that a user uploads).
The code below works perfectly. HOWEVER when done on chrome on windows. if the bigger image is a really high res (lets say 4400 x 4000). The screen would go white and the image would disappear. The white bursts out of the container (which has overflow:hidden) on it and covers the screen. Only the elements with a higher z-index over the image displays.
If I inspect the element that is white. It shows that it is the element, and the image is loaded - the URL is fine and if I click the image to open in another tab it loads fine.
Does anyone have any idea why this is happening?
if(href){
var img = document.createElement('img');
img.className = 'openLBFullView hidden';
img.onload = function(){
loadBiggerImg(this);
};
$(img).data('url',$currentImg.data('url'));
img.src = href;
img.id = 'my-image';
}
var loadBiggerImg = function(img){
var originalImg = $('#my-image');
//append the img to the document
originalImg.before(img);
// append original styles and classes to new image
$(img).attr('style',originalImg.attr('style'));
$(img).attr('class',originalImg.attr('class'));
// fix for windows IE adding attributes
$(img).removeAttr('width').removeAttr('height');
//fade in new image over the top and remove old one
$(img).fadeIn(200,function(){
originalImg.remove();
});
}
One of the possible solutions - large images dont render in chrome
This not neccesarily will fix your issue though - I'd try using lowres jpegs scaled to highres and preload big one - once loaded fade lowres one and show the big one (in a way fake the progressive JPEG) - Hope that helps man.
Related
I have looked over examples online, yet I believe I am overlooking something. I have two similar images that need to be rendered when the screen is at a different size. One image at 1440px screen size and one at 375px screen size. Right now with my code I have set the initial source to render the "mobile view" of the image, and with the srcset of the desktop view image at 1440w. When I load up live server it shows the desktop image, and not the initial source of the mobile view. So it seems to be working but missing a step.. any tips are greatly appreciated!
<img
class="future__container--img"
src="./images/illustration-editor-mobile.svg"
srcset="./images/illustration-editor-desktop.svg 1440w"
alt="illustration-editor-mobile"
/>
So when the browser first loads it is showing the desktop.svg, but when I set the browser to 375px it still displays the desktop.svg. I first had this written in javascript ..
const resizeEditiorImg = () => {
const reswidth = screen.width;
let image = document.querySelector(".future__container--img");
if (reswidth >= 1440) {
image.src = "../images/illustration-editor-desktop.svg";
} else {
image.src = "../images/illustration-editor-mobile.svg";
}
};
window.addEventListener("resize", resizeEditiorImg);
But the issue here is that when the browser first loads on desktop view, it is displaying the mobile image unless the user manually resizes the browser, which is what I believed at first. I hope this post makes sense!
This only work in resize browser because this code resizeEditiorImg
you need run this command resizeEditiorImg in your load page.
example
<body onload="resizeEditiorImg()">
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.
js to load a video, this is fine.
I'm using Popcorn Capture to capture the current frame, copy it into an image which is attached to the body. This appears to be working. An image of the frame shows, and pauses.
What I want to happen is to keep this image at the top level, do some stuff underneath and then fade this image away when ready for a nice transition.
What I get is
image shows
layer underneath renders
video starts again above new rendered layer, unless I remove the video with jQuery which removes the image as well.
I can't seem to even destroy/get rid of video without removing the image.
Here's the code
image = document.createElement("image");
image.id = "capture";
image.setAttribute("class", "video-js");
img = currentVideo.pause().currentTime( 0 ).capture({
target: "img#capture",
media: true
});
image.src = img;
document.body.appendChild(image);
$("#capture").fadeTo("slow" , 0);
currentVideo.src = '';
currentVideo.load();
currentVideo.destroy();
videoPlaying = false;
createScene();
$('#video').remove();
$('#prevButton').show();
$('#openGuide').show();
$('#openSceneInfo').show();
Any clues on how to make sure that image stays on screen, and then can be faded away?
Just faded out the video element with fadeTo. This worked better.
I load a lot of images to my site and it works fine if I'm patient. But sometimes I fire an action with myDiv.style.display = 'none'; in it during image load and then the image gets width=height=0, for all the images haven't been completed. When I make my div visible again I can't see them but identify by searching for width=height=0.
If I set the width and height to something bigger than 0, I see the images but in this way I lose the real size. I also tried to change image.src by adding something like myImage.src += "?t=random";. Doing this, myImage.onload function gets fired again but width and height are still 0.
How can I get the real size of the images or how can I force a reload?
You can attach an event to your image elements:
image.onload = function () { /* Your code here */ };
This will fire when the image is actually loaded.
Make sure this event is attached before you set the src element and make sure that your src is actually valid. You can check this in the Network panel in Google Chrome (F12 on Windows).
Taking a deeper look i found following Workaround.
When the image is loaded the first time, it has a valid width and height but doesn't get painted because of the div is not visible. When I make the div visible again and initiate the reload by changing the image URL like myImage.src+="?t=random" the image.onload gets fired with the image width and height of 0. So what I can do is just to save the original values and use them if needed.
// save or reload image size in case of load interruption
if (typeof this.orgWidth == 'undefined' && this.width>0) this.orgWidth = this.width;
if (typeof this.orgHeight == 'undefined' && this.height>0) this.orgHeight = this.height;
if (this.width==0) this.width=this.orgWidth;
if (this.height==0) this.height=this.orgHeight;
i have a div element, with very big size background image. so, is it possible, to set a little size image as backgrount, untill the big size image loads.
thanks
I guess you could put another div element underneath it (using the z-index property) and give that the faster loading background image.
Whether that is practical to do, depends on your Layout, you'd have to give more information about that.
There's also the ages-old lowsrc HTML 4 property that still seems to be pretty well supported (I have not tried it myself since Netscape 4), but that won't work for background images.
CSS:
.that-div {
background-image:url(/path/to/small-image.png);
}
jQuery:
$(function () {
var bigImg = new Image(),
bigImgSrc = '/path/to/big-image.png';
bigImg.src = bigImgSrc;
$(bigImg).load(function(){
$('.that-div').css('background-image':'url('+bigImgSrc+')');
});
});