I tried adding a preloading function to my JS application. Basically it should only continue when all images are ready to display. Waiting for image.onload is the first step, but Firefox also needs some time appending the image to the document. In the following example the red background should not be visible because in theory the image is already there.
document.body.style.margin = "0";
document.body.style.background = "#000";
var img = document.createElement("img");
img.style.width = "100%";
img.onload = function()
{
// Add the image
document.body.appendChild(img);
// Then set BG to red - which should not be visible
document.body.style.background = "#F00";
}
img.src = "https://upload.wikimedia.org/wikipedia/commons/9/9d/Wikidata_Map_July_2017_Huge.png";
However in this example the red background is visible (up to 2 seconds on my system). I guess Firefox requires certain CPU power to append and shrink the image to 100% width. The problem didn't appear in Chrome or Safari.
How can I detect if the image is actually visible or still being processed?
Related
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 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.
This is really for informational and learning purposes while learning more about JavaScript and CSS. I have a local browser index page that I wanted to rotate the background image onload. After looking around and playing with different solutions, I settled on this for the basic rotate functionality:
<html>
<head>
<script language="javascript" type="text/javascript">
function rotate()
{
var imgArray = new Array("img1.jpg", "img2.jpg", "img3.jpg");
var aImg = Math.floor(Math.random()*imgArray.length);
var img = imgArray[aImg];
document.body.style.background = "url(" + img + ") no-repeat";
document.body.style.backgroundSize = "cover";
}
</script>
</head>
<body onload="rotate()">
</body>
</html>
During the process, before I just set the backgroundSizeas cover to fill the window, I was playing with the idea of resizing the images before setting them as the background image after they are selected from the array.
I have done a lot of searching, and the only real working solutions I have found rely on selecting the element by ID, but that also requires that the image has an ID associated, such as in the IMG property in the HTML code. Here the image is selected and set in the JavaScript with CSS.
I have tried setting the image dimensions with img.width / img.height and img.style.width / img.style.height, as well as a few other random solutions I have come across, but whenever I try to change these the image either does not change or it does not show at all.
function rotate()
{
var imgArray = new Array("img1.jpg", "img2.jpg", "img3.jpg");
var aImg = Math.floor(Math.random()*imgArray.length);
var img = imgArray[aImg];
image = rsize(img);
document.body.style.background = "url(" + image + ") no-repeat";
document.body.style.backgroundSize = "cover";
}
function rsize(image)
{
image.style.width = "300px";
image.style.height = "300px";
return image;
}
I know I am probably doing something wrong here. Is there a way, in this circumstance, that I can resize these images? Or is there a better way to construct this?
Thanks in advance.
You must set image.style.width and image.style.height on an actual image DOM object, not on the URL as you are currently trying to do.
As an image object is not used for background images, you can't really directly do what you're trying to do for a background image.
You could use the CSS background-size property, but that is fairly new and is not supported in versions of IE prior to IE9. If you were using that, you would set the actual size for that, not "cover".
You could also use an actual DOM image and then present that DOM image as centered in your page if that's what you're really trying to do.
For example, here's how you create a DOM image object, assign it a URL, set it's size and insert it into your page:
var imgArray = new Array("img1.jpg", "img2.jpg", "img3.jpg");
var aImg = Math.floor(Math.random()*imgArray.length);
var imgURL = imgArray[aImg];
var img = new Image();
img.src = imgURL;
img.style.width = "300px";
img.style.height = "300px";
img.id = "centeredImage";
document.body.appendChild(img);
You could then use CSS to position is in the center of your page if you wanted.
Working demo here: http://jsfiddle.net/jfriend00/jqMtV/
No, you have no <img> elements you could (re)size (btw, they would not need ids to be selectable). Your use of rsize(imgArray[aImg]) operates on the array members, which are strings and not DOM elements, so setting values on their non-existent style property would throw an error.
Yet, you're already on the right way with using the backgroundSize style property. Just don't set it to cover, but to the size you need!
document.body.style.backgroundSize = "300px 300px";
If you would want to use a <img> element, add this at the end of your <body>:
<img src="some.jpg" style="position:fixed; z-index:-1; width:100%; height:100%" />
I have a javascript "loading" function like this:
function splashScreen() {
var div = document.createElement('div');
div.appendChild(document.createTextNode("some text"));
div.style.position = "fixed";
div.style.width = "100%";
div.style.height = "100%";
div.style.left = "0";
div.style.top = "0";
div.style.zIndex = "1000";
div.style.background = "white url('img/ajax-loader.gif') no-repeat center";
div.style.fontSize = "x-large";
div.style.textAlign = "center";
div.style.lineHeight = "3em";
div.style.opacity = "0.75";
div.style.filter = "alpha(opacity=75)"; // fix ie
document.body.appendChild(div);
return true;
}
I use this function in the form action (onsubmit="return splashScreen()") to show a "rotating logo" while the next page load...
The problem is in that "img/loading.gif" and safari (on winXP): in ff and ie I have no problems, and I clearly see the animated gif. In safari I can't see it.
If I change the image with a (obviously static) png the image appears...
Am I doing something wrong? What's the problem with safari?
Safari doesn't handle animated background well enough. I've seen a bug report about that somewhere.
Why don't you just use an image instead of a background?
I'm not personally familiar with this issue, but I was able to find a handful of similar bug reports online. What else are you doing on this page? Are you keeping focus on the page when you experience this issue? Apparently the handling of animated GIFs is pretty complicated:
http://webkit.org/blog/96/background-music/
http://www.quirksmode.org/bugreports/archives/2004/12/animated_gifs_u.html
https://bugs.webkit.org/show_bug.cgi?id=7320
Particularly relevant snippet from that first link:
In both Safari 2 and WebKit nightlies, GIFs don’t animate unless they are being painted somewhere. If an animated GIF becomes invisible, then the animation will pause and no CPU will be consumed by the animation. Therefore all animated images in a background tab will not animate until the page in that tab becomes visible. If an animated GIF is scrolled offscreen even on a foreground page, it will stop animating until it becomes visible again.
Safari’s CPU usage with animated GIFs is very good. (For a while readers of MacNN thought Safari had an “animated GIF problem” because of slowness when typing in forum posts, but that bug actually had to do with the Flash ads at the top and bottom of the page.)
Maybe it's your gif image? I just fired up your code on Safari 4.0.4 under windows with a gif created on http://www.ajaxload.info/ and works flawlessly.