Loading image delayed display after loaded - javascript

So I have this html / css / jQuery / js code that toghether shows a VERY large image in width. The base element should be invisible untill the image is loaded and set. Then the base element is made visible by a small fade.
However the behaviour is a little different.
Once the image is being loaded i can see the small text fading in and it takes a few seconds before then the image just pops up in once (not loading style like from top to bottom appearing)
This is the simplified code i use:
<script>
$(function() {
$("#base").hide();
var baseHeight = $(window).height();
var backLayerSRC = $('#img').attr('data-src');
$('#base').height(baseHeight);
var img = new Image();
var imgWidth, imgHeight;
img.onload = function() {
imgHeight = this.height;
imgWidth = this.width;
var factor = 1 * baseHeight / imgHeight;
totalWidth = Math.round(factor * imgWidth);
currentWidth = totalWidth;
$('#base').width(totalWidth);
$('#img').attr('src', backLayerSRC);
$('#img').height(baseHeight);
$('#base').fadeIn(500);
};
img.src = backLayerSRC;
});
</script>
<style>
#base {
position:absolute;
left:0px;
height:100%;
}
#base #img {
position:absolute;
left:0px;
top:0px;
}
</style>
<div id='base'>
some tekst
<img src='' id='img' data-src='path_to_very_large/image.png' />
</div>
Now, how could it be that it just doesn't fade in WITH the image?
Here is an example WITH the image, please check so it becomse clear what i mean
http://jsfiddle.net/uz8mvtap/3

It might depend on the time the browser needs to render the image after the script loaded it.
I played a little with your fiddle and came up with this:
$(function() {
$("#base").css({opacity: 0});
var baseHeight = $(window).height();
var backLayerSRC = $('#img').attr('data-src');
$('#base').height(baseHeight);
var img = new Image();
var imgWidth, imgHeight;
img.onload = function() {
imgHeight = this.height;
imgWidth = this.width;
var factor = 1 * baseHeight / imgHeight;
totalWidth = Math.round(factor * imgWidth);
currentWidth = totalWidth;
$('#base').width(totalWidth);
$('#img').attr('src', backLayerSRC);
$('#img').height(baseHeight);
$('#base').delay(1000).animate({opacity: 1.0},500);
};
img.src = backLayerSRC;
});
Basically using opacity for such a purpose is better because #base continues to occupy the same space, not disrupting the page. And the delay is for the browser, I figured for a big image it takes time to render, so let's give it it.

You could do that.
$('<img />').load( function(){
console.log('loaded');
}).attr('src', imgUrl);
After it loads, it summons a callback, use that callback to do custom function. Let me know how it goes.
or, by the way. You could enter image width and image height into custom var, and compare them on the load, once it reaches your wanted width and height, fade it in.

You seem to be slightly misinterpreting the timeline of your code:
Page loads, (text is visible on screen)
jQuery kicks in, hides #base (text is not visible on screen)
jQuery fades in #base (text is visible on screen again)
This is why you are briefly seeing the text before the image loads - because it is not initially hidden.
Add:
display: none;
To your #base style, add keep the rest of your code the same.
Also I've created an alternative JavaScript solution after you have added the above CSS:
$(function() {
const base = $("#base"),
img = $("#img"),
backLayerSRC = img.attr('data-src'),
baseHeight = $('#base').height();
img.attr('src', backLayerSRC);
img.one("load", () => {
img.height(baseHeight).promise().done(() => { base.fadeIn(2500); });
});
});

Here is the working example of your code I have created:
https://codebrace.com/editor/b16cabfee
Your baseHeight variable is undefined.
May be you should change
$('#base').height(baseHeight);
to
var baseHeight = $('#base').height();
Update:
I have updated the solution. I this solution I have wrapped div around both the text and image. Div wrapped around image is set to position:relative; to keep the image(set to absolute position) from covering the text.
https://codebrace.com/editor/b16f33afb

Related

Why does the Jcrop-tracker not show it's correct position?

In my app users can take a picture or upload an image from their device. This image is the source for a Jcrop function. This function works correctly, as in it 'crops' correctly. However the jcrop-tracker that previews what you are cropping doesn't show it's correct position on the image.
Please see this example:
When moving the tracker to the top of the image, it'll show almost the entire image. When moving further down, it'll show nothing at all. How is this possible?
My guess is this is because of jCrop having issues with downscaled pictures (for example pictures taken from device camera).
I use CSS to downscale the image so it can fit on on device screen:
#imgContainer {
max-width: 100%;
max-height: 100%;
}
#imgContainer img {
max-width: 100%;
max-height: 100%;
}
Is there any way to prevent this?
Here's my code:
$(window).load(function() {
var jcrop_api, boundx, boundy;
function updatePreview(c) { // croping image preview
if (parseInt(c.w) > 0) {
var rx = 220 / c.w, ry = 220 / c.h;
}
}
function showCoords(c) { // show all coords
$('#x').val(c.x);
$('#y').val(c.y);
$('#x2').val(c.x2);
$('#y2').val(c.y2);
$('#w').val(c.w);
$('#h').val(c.h);
}
$('#cropImage').Jcrop({
onChange: updatePreview,
onSelect: showCoords,
bgFade: true,
bgOpacity: .8,
aspectRatio: 1,
maxSize: [ 150, 150 ],
boxWidth: 284,
boxHeight: 382
},function(){
jcrop_api = this;
});
var canvas = document.getElementById("canvasresult");
$("#m1-cropScreen-cropIt").on("click", function(){
var context = canvas.getContext("2d");
var img = document.getElementById("cropImage"),
$img = $(img),
imgW = img.naturalWidth,
imgH = img.naturalHeight;
console.log($img.width());
console.log($img.height());
var ratioY = imgH / $img.height(),
ratioX = imgW / $img.width();
var getX = $('#x').val() * ratioX,
getY = $('#y').val() * ratioY,
getWidth = $('#w').val() * ratioX,
getHeight = $('#h').val() * ratioY;
context.drawImage(img,getX,getY,getWidth,getHeight,0,0,150,150);
$('#cropResult').attr('src', canvas.toDataURL());
});
});
Gentleman, I'm sorry for the delay in responding to you. Thank you everyone who replied on my question.
I've had a very busy week so I had little time to work on this project. Today I've picked it up again and I first tried to solve this problem myself again.
Fortunately, this time it worked. I ended up using Jcrop's box sizing method. I believe I had tried it before, but this time it works flawlessly. So problem solved :)
Unfortunate this did not work for me but I had a different issue that I hope will help anyone else who has this this issue.
Mine was due to a css styling conflict.
From a 3rd party style sheet
img { max-width: 100% }
My Style Sheet -- adding this fixed it
.jcrop-holder img, img.jcrop-preview { max-width: none !important }

jQuery not firing on load/ready when server responce is slow

I fire a function on jQuery(document).ready() and on jQuery(window).load(). Both the same function. It is supposed to fire an image resize script.
However, sometimes, when the server is slow to respond, the script doesn't fire at all when the page is done loading.
I've been having this problem for quite a while now, and, maybe it's overkill, but by now, I call the function as shown below, in both the document ready and the window load:
jQuery('img', '.background').each(function(){
jQuery(this).load(function(){
jQuery(this).resizeImage();
});
});
The function it calls is:
jQuery.fn.resizeImage = function() {
console.log('fired');
var bgImg = jQuery(this);
/* get img sizes */
var imgwidth = bgImg.width();
var imgheight = bgImg.height();
/* get window sizes */
var winwidth = jQuery(window).width();
var winheight = jQuery(window).height();
/* get the ratio, checks wether window is bigger or smaller than the image */
var widthratio = winwidth / imgwidth;
var heightratio = winheight / imgheight;
/* checks the difference */
var widthdiff = heightratio * imgwidth;
var heightdiff = widthratio * imgheight;
/* if you want the entire image to always fit the screen, change the > to < */
if(heightdiff>winheight) {
bgImg.css({
width: winwidth+'px',
height: heightdiff+'px',
marginLeft: '-'+winwidth/2+'px'
});
} else {
bgImg.css({
width: widthdiff+'px',
height: winheight+'px',
marginLeft: '-'+widthdiff/2+'px'
});
}
};
Using the console.log, I found that the function doesn't fire at all.
Can anyone point me in the right direction as to why this might not work?
Guess you're miss using the this
jQuery('img', '.background').each(function(){
var $self = $(this);
$self.load(function(){
$self.resizeImage();
});
});
Solved it myself.
The issue was in the following:
jQuery(window).load(function(){
jQuery('img', '.background').each(function(){
jQuery(this).load(function(){
jQuery(this).resizeImage();
});
});
});
Due to the double load (jQuery(window).load and jQuery(this).load) the code didn't execute at all. Since when the window is loaded, the images are already loaded as well.

Get full size of image in javascript/jquery

I have an image on page that has been resized to fit in a div, say, 400x300. How can I get the full size of the image (~4000x3000) in jQuery? .width() and .height() only seem to return the current size of the image.
Images have naturalWidth and naturalHeight properties that contain the actual, non-modified width and height of the image, i.e. the real dimensions of the image, not what CSS sets it to.
One would still have to wait for the image to load though
$('#idOfMyimg').on('load', function() {
var height = this.naturalHeight,
width = this.naturalWidth;
});
Another option would be to create a new image with the same file as the source, and get the dimensions from that, as long as it's never added to the DOM, not external styles will affect it
var img = new Image();
img.onload = function() {
var height = this.height,
width = this.width;
}
img.src = $('#idOfMyimg').attr('src');
FIDDLE
You can clone the image, remove the height and width attributes, append it to the body and get the width and size before removing it.
jsFiddle demo is here: http://jsfiddle.net/58dA2/
Code is:
$(function() {
var img = $('#kitteh'); // image selector
var hiddenImg = img.clone().css('visibility', 'hidden').removeAttr('height').removeAttr('width').appendTo('body');
$('#height').text(hiddenImg.height());
$('#width').text(hiddenImg.width());
hiddenImg.remove();
});​
You can do this with an Image object that holds the same source file like:
var preloader = new Image();
preloader.src = 'path/to/my/file.jpg';
preloader.onload = function(){
var height = preloader.height;
var width = preloader.width;
}
Try this:
var pic = $("img")
// need to remove these in of case img-element has set width and height
pic.removeAttr("width");
pic.removeAttr("height");
var pic_real_width = pic.width();
var pic_real_height = pic.height();

Getting original image for cropping, ignoring the width attribute?

My user can upload really big images, and for cropping and display purposes i'm adding width attribute so it will fit well in the browser window. Real image size can be - say 1920 x 1080 px.
<!-- width added for display purpose -->
<img class="croppable" src="images/fhd.jpg" width="640" />
In order to calculate real selection box dimension (if the x coordinate is 20px then would be 60px in the original full hd picture) i need to get the full image size before apply the width attribute.
The problem is that this will return 640 as value, taking into account the width attribute:
// Important: Use load event to avoid problems with webkit browser like safari
// when using cached images
$(window).load(function(){
$('img.croppable').each(function(){
alert(this.width);
});
});
Please don't flag this as duplicate since what i'm asking is completly different from simple image width/height retrival (which works, actually).
EDIT: Chris G. solution seems not working:
$(window).load(function(){
$('img.croppable').each(function(){
console.log(this.src);
var original = new Image(this.src);
console.log(original);
$("#original_w").text(original.width); // Temp, more images to be added
$("#original_h").text(original.height); // Temp, more images to be added
});
});
Console output:
http://localhost/DigitLifeAdminExtension/images/pillars-of-creation.jpg
<img width="0">
Get the width/height of the image itself, not the div it is contained within.
$(window).load(function(){
$('img.croppable').each(function(){
var img = new Image();
img.src = $(this).src;
alert(img.width);
});
});
You can remove the attributes, get the width and put the attributes in place again:
var $img = $(img);
var oldWidth = $img.attr("width");
var imgWidth = $img.removeAttr("width").width();
$img.width(oldWidth);
But I think Chris G.'s answer works well too, just making sure it will be loaded when you try to get the width:
img.onload = function() {
if (!img.complete) return; // IMG not loaded
width = img.width;
imgManipulationGoesHere();
}
Works in most up-to-date browsers and IE9.
$(window).load(function(){
$('img.croppable').each(function(){
alert(this.naturalHeight);
});
});
The working solution would be:
$(function(){
$('img.croppable').each(function () {
var original = new Image(this.src);
original.onload = function () {
alert(original.src + ': ' + original.width + 'x' +original.height);
};
});
});

How to get the downloaded image's width&height?

I want to set the width and height of the container <div> of <img> after the image is downloaded, how to do it?
function fn (div, url_path) {
var img = new Image();
img.onload = function () {
div.style.width = img.width;
div.style.height = img.height;
};
img.src = "url_path";
}
fn(document.getElementsByTagName('div')[0], 'http://some-url-to-image.com/1.jpg');
Put it on the page hidden, then measure its width. See here for a good explanation of how to measure the width of a hidden object (just calling width() returns 0).
It is best to wait for the image to be loaded unless you want false results.
jQuery('#image').load(function() {
var jThis = jQuery(this);
var width = jThis.width();
var height = jThis.height();
yourFunction(width, height); //whatever you want to do with these values
jThis.unbind('load'); //might be necessary if you only want this to happen once. Remove this if #image is a container for multiple uses.
})
EDIT 1
Instead of yourFunction(), you could use this since it fits your description better:
jThis.parents('#container').css({
width: width,
height: height
});

Categories