Getting dimensions of background-image - javascript

I'm trying to get width and height of element's background-image. When you click on it, it should show it inside the element ("200 300" in this case).
HTML:
<div id='test'></div>
CSS:
#test {
width: 100px; height: 100px;
background-image: url(http://placehold.it/200x300);
}
JavaScript:
$('#test').on('click', function () {
$(this).text(getDimensions($(this)));
});
var getDimensions = function(item) {
var img = new Image(); //Create new image
img.src = item.css('background-image').replace(/url\(|\)$/ig, ''); //Source = clicked element background-image
return img.width + ' ' + img.height; //Return dimensions
};
Here's the Fiddle. The problem is it works only in Chrome, all the other main browsers return "0 0". I have no idea what's the reason. Isn't that graphic fully loaded?

The issue is that some browsers add quotes to the CSS, and it was trying to load (in the fiddle's case) "http://fiddle.jshell.net/_display/%22http://placehold.it/200x300%22". I've updated your .replace() to look for " as well, and a fiddle is at http://jsfiddle.net/4uMEq/
$('#test').on('click', function () {
$(this).text(getDimensions($(this)));
});
var getDimensions = function (item) {
var img = new Image();
img.src = item.css('background-image').replace(/url\(|\)$|"/ig, '');
return img.width + ' ' + img.height;
};

I guess you need to wait for onload event on image.

Related

Use jQuery zoom on background image

I'd like to use the jQuery zoom on background images. The problem is, it works on images with img tags only. Is there any way to use it on background-images aswell?
I can't use img tag, because this value comes from javascript.
For example, I have this div:
<div class="main-image" style="background-image: url("image.jpg");"></div>
$(document).ready(function() {
$('.main-image').zoom();
});
(function() {
let gallerys = document.querySelectorAll('.gallery');
gallerys.forEach(gallery => {
updateGalleryPictures(gallery);
});
})();
function updateGalleryPictures(gallery) {
// Get gallery's thumbnail images
let thumbnails = gallery.querySelectorAll('.thumbnail');
// Change the background-image property on click
thumbnails.forEach(thumbnail => {
thumbnail.addEventListener('click', () => {
updateMainImage(gallery, thumbnail.src)
});
});
// Initialize background-image property using the 1st thumbnail image
let firstThumbnail = thumbnails[0];
if (firstThumbnail === null || firstThumbnail === undefined) return;
updateMainImage(gallery, firstThumbnail.src)
}
function updateMainImage(gallery, src) {
// Get main image and check if it exists
let mainImage = gallery.querySelector('.main-image');
if (mainImage === null) return;
mainImage.style.backgroundImage = 'url(' + src + ')';
}
The following is the source code of the plugin in question. https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js - it is not designed to work on background images as you can see from lines https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js#L117 and https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js#L231 two properties which aren't available on divs.
You may get some mileage using pure CSS moving on mousemove something like:
$('.main-image').mousemove(function(e){
var amountMovedX = (e.pageX * -1 / 2);
var amountMovedY = (e.pageY * -1 / 2);
$(this).css({
'background-size': '200%',
'background-position': amountMovedX + 'px ' + amountMovedY + 'px'}
);
});
.main-image {
background-image:url('https://www.travelandleisure.com/sites/default/files/styles/tnl_redesign_article_landing_page/public/1453920892/DUBAI-554088081-ABOVE0116.jpg?itok=dcoZnCrc');
background-size: 100%;
display:block;
height:200px;
width:200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-image">
</div>

Trigger function after background-image is loaded

I am using Jimdo and have a given div (containing 3 sub-divs, I think this is my general problem, but I am not sure) I found with the browser:
<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>
How do I get a function triggered after the background-image of this is loaded?
I've already spent hours into this, tried tons of ways I found here or tools like waitforimages - still without success. What is going on with Jimdo / this div?
How do I get something triggered after the background-image is loaded?
var src = $('.jtpl-background-area').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');
var img = new Image();
img.onload = function() {
$('.jtpl-background-area').css('-webkit-animation', 'fadein 4s');
}
img.src = url;
if (img.complete) img.onload();
does not work.
$('.jtpl-background-area').waitForImages(true).done(function() {
$('.jtpl-background-area').css('-webkit-animation', 'fadein 4s');
});
does not work (waitforimages-script is included correct and opacity of .jtpl-background-area is set to 0 in css).
Any ideas?
$(window).on('load', function() {
$(".jtpl-background-area").css('-webkit-animation', 'fadein 4s');
});
causes backgrounds often popping up too late. Page is displayed while pictures are still not ready/fully loaded.
-
Edit:
Regarding Scott Marcus and the answer here by 'adeneo' (Wait for background images in CSS to be fully loaded):
$(window).on('load', function() {
$(".jtpl-background-area jqbga-container jqbga-web-
image").ready(function() {
$(".jtpl-background-area").velocity({ opacity: 1 },{ duration: 3000});
})
});
This here "works" - but my bg-images popping up too late.
But why does nothing happen if I exchange this with
var src = $(".jtpl-background-area jqbga-container jqbga-web-image");
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');
var img = new Image();
img.onload = function() {
$('.jtpl-background-area').velocity({ opacity: 1 },{ duration: 3000});
}
img.src = url;
if (img.complete) img.onload();
?
Where is my mistake? Why doesnt this work and make my page stuck? It stays white and fails to load at all with this code.
Or in other words - how do I get
var src = $('#test').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');
var img = new Image();
img.onload = function() {
alert('image loaded');
}
img.src = url;
if (img.complete) img.onload();
to work with my (given and unchangeable)
<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>
exactly?
Instead of using a background image, you can use an img element and CSS positioning to layer it behind the content of its parent div. Then, you can use the load event of the img element.
document.querySelector(".jtpl-background-area").addEventListener("load", function(){
console.log("Background loaded!");
$(".hidden").fadeIn(4000); // Fade the image in
});
/* by positioning the element absolutely and giving it a negative
z-index, we put it behind any other items in the same space. */
.jtpl-background-area { position:absolute; z-index:-1; top:0; left:0; }
div div { background-color:rgba(255,255,255, .5); }
.hidden { display:none; } /* Image will start off hidden */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div>Some other div content</div>
<!-- The image will be hidden at first -->
<img class="hidden jtpl-background-area jqbga-container jqbga-web--image" background-area="" src="http://imgsrc.hubblesite.org/hvi/uploads/image_file/image_attachment/30741/STSCI-H-p1821a-m-1699x2000.png">
</div>
So here is what I came up with. We are basically creating an image, waiting for the file to load, then applying a style to the container.
Basically, we are making sure that no background-image is shown when the page loads by setting background:none !important; to the container.
We then create a new Image with JS, once that image's source is loaded, we apply a new class to the container, which sets the background image. You can add the animation and/or the opacity at your own discretion.
You may or may not have to fiddle around with the !important flag for your use case.
Is this what you had in mind?
$(document).ready(function() {
var img = new Image();
var container = $('.container');
img.src = "https://placeimg.com/640/480/any";
img.addEventListener('load', function() {
container.addClass('hasBackgroundImage')
});
});
.container {
opacity: 0;
background: none !important;
}
.hasBackgroundImage {
opacity: 1;
background-image: url('https://placeimg.com/640/480/any') !important;
background-size: cover;
height: 500px;
width: 500px;
transition: all ease-in-out 4s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>
You might do it like this:
Script starts working before the document has been loaded.
It intercepts the inline style of your div before it's been applied.
Then uses Image object to load the image and sets the background-image onload.
var i = setInterval(function() {
var div = document.querySelector('.jtpl-background-area');
if (div) {
clearInterval(i);
var src = div.style.backgroundImage.replace(/^url\(['"]?|['"]?\)/ig, '');
div.style.backgroundImage = 'none';
var img = new Image();
img.onload = function() {
div.style.backgroundImage = 'url(' + src + ')';
div.classList.add('loaded')
img = null;
}
img.src = src;
}
}, 10);
.jtpl-background-area {
width: 330px;
height: 200px;
opacity: 0;
}
.loaded {
transition: opacity 2s linear;
opacity: 1;
}
<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>
Hope this helps.

How to refresh offsetHeight of div after changing img src on child using pure javascript?

I need to change an image in a div and then immediately centre it on the screen by calculating its height and width and then setting its left and top values. But when I change the img src and then try to get the div's offsetHeight and clientHeight, both the values are wrong. Strangely the offsetWidth and clientWidth values are correct.
Is there a way to refresh the div and get the correct value?
Edit: It appears that changing the image src makes everything after that not work. The change to the onclick event imageObj.onclick = function() {contractImageView(imageId);}; isn't working now either. If I comment out the if statement it all starts working again.
Below is the code...
// Get the page dimensions
var pageBody = document.getElementById(currentBody);
// If you couldn't get the page body, abort.
if (!pageBody) {
return;
}
var pageBodyHeight = window.innerHeight;
var pageBodyWidth = pageBody.offsetWidth;
var imageDiv = document.getElementById(imageId);
var imageObj = imageDiv.children[0];
var paraObj = imageDiv.children[1];
// If you can't get the div or its image, then abort.
if (!imageDiv || !imageObj) {
return;
}
// Check whether the image has been loaded yet, and load if needed
if (imageObj.src.indexOf('lazy_placeholder.gif') !== -1) {
for (item in photoLazyData) {
if (item === imageDiv.parentElement.id) {
imageObj.src = photoLazyData[item][imageDiv.id];
}
}
}
// Change the images class.
imageDiv.className = 'active_design_div';
imageDiv.style.visibility = 'visible';
imageDiv.style.opacity = 1;
// Set the objects new onclick method to collapse the image
imageObj.onclick = function() {contractImageView(imageId);};
// Calculate the right size
imageDiv.style.maxHeight = pageBodyHeight + 'px';
imageDiv.style.maxWidth = pageBodyWidth + 'px';
imageObj.style.maxHeight = pageBodyHeight + 'px';
imageObj.style.maxWidth = pageBodyWidth + 'px';
// Calculate the margins.
var imageDivWidth = imageDiv.offsetWidth || imageDiv.clientWidth;
// ## THIS IS WRONG IF THE ABOVE IF STATEMENT CHANGES THE SRC ##
var imageDivHeight = imageDiv.offsetHeight || imageDiv.clientHeight;
console.log(imageDiv.offsetHeight + ' : ' + imageDiv.clientHeight);
console.log(imageDiv.offsetWidth + ' : ' + imageDiv.clientWidth);
var leftOffset = (pageBodyWidth - imageDivWidth) / 2;
var topOffset = (pageBodyHeight - imageDivHeight) /2;
// Adjust styling to make the div visible and centred.
imageDiv.style.left = String(leftOffset) + 'px';
imageDiv.style.top = String(topOffset) + 'px';
currentId = imageId;
toggleBlackDiv();
Edit: I got this working in the end using Joonas89's answer. I basically moved the if statement that changes the src value to another function that is called prior to the one above. This solved the onclick problem mentioned above. I then changed the divs left/top from calculated values to 50% as detailed by Joonas89 (but on the container div rather than the img element), along with the new transform property. The div and img already had a position value of fixed so didn't need to change that.
Are you sure u want to calculate top and left positions? Wouldent it be better to add a class like this, that always centers it
.parentDiv{
position: relative;
}
.imageElement{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

Safari, Chrome runs code in window.load before page loaded

I have some html that looks like this:
<div class="nmMap-wrapper">
<div id="draggable" class="nmMap-image">
<div class="nmMap"></div>
</div>
</div>
and on the "nmMap" I have a background image set in the css.
I then have a javascript loading the background image, appdending it as a image, and then getting the width and height, and alerting all the diffirent variables.
The script looks like this:
jQuery(window).load(function($) {
sceneConstructor();
});
function sceneConstructor() {
var bgHeight;
var bgWidth;
var bgAspectRatio;
function init() {
getBgSize();
alertRatio();
}
function getBgSize() {
var bgsrc = jQuery('.nmMap').css('background-image')
.replace('url("', '')
.replace('url(', '')
.replace('")', '')
.replace(')', '')
.replace('"', '')
.replace("'", '');
var bgImg = jQuery('<img />');
//bgImg.hide();
jQuery('.nmMap').append(bgImg);
bgImg.attr('src', bgsrc);
bgImg.bind('load', function() {
var width = jQuery(this).width();
var height = jQuery(this).height();
alert('first height' + height);
setAspectRatio(width, height);
});
}
function setAspectRatio(width, height) {
alert('second height: ' + height);
bgHeight = height;
bgWidth = width;
bgAspectRatio = bgWidth / bgHeight;
alert('trejde: ' + bgHeight);
jQuery('.nmMap').addClass('ration');
}
function alertRatio() {
alert('bgheight ' + bgHeight);
alert('bgwidth ' + bgWidth);
alert('bgheight ' + bgHeight);
alert('bgaspect ' + bgAspectRatio);
}
init();
}
All this working in firefox, except that the first alert in alertRatio() always gets undefined. But in safari, chrome, and IE, it's like alertRaiom() is being run first, and because of that all the alerts are undefined.
Can someone help and tell me whats going on?
try the default .ready from jquery.
this code load after the dom is loaded.
jQuery( document ).ready(function() {
sceneConstructor();
}):
you can also
jQuery( window ).ready(function() {
sceneConstructor();
}):
source: https://api.jquery.com/ready/
Does it help if you bind() the event listener before you set the image's src attribute?

Resize Image to it's original dimension using jQuery Animation

I want to animate an image from 200 x 300px to its original size using jQuery.
I have this picture:
var imgHtml = "<img id='bigImg' src='" + bigSrc + "' alt='' style=\"height:200px; width:300px\"/>";
$("#divId").html(imgHtml);
And this jQuery code:
$("#bigImg").animate({
height: "400px",
width: "600px",
},500);
It works well, but I actually have to hardcode the future size. I would like to animate to the original size.
How can I do this ?
Try doing this
HTML
<div id="divId">Loading</div>
<input id="submit" type="button" value=" Click Me " />
JavaScript
var bigSrc = "Image Source";
var img = new Image(),
oWidth, oHeight;
img.onload = function() {
oWidth = this.width;
oHeight = this.height;
this.width = 300;
this.height = 200;
this.id = "bigImg";
}
img.src = bigSrc;
$("#submit").click(function(e) {
$("#divId").append(img);
$("#bigImg").animate({
height: oHeight,
width: oWidth,
}, 500);
});​
Check this demo jsFiddle
You can tweak to suit you. Hope this helps you.
Okay, I see what you mean now.
$("#bigImg").width() will return the width in px, and height will do similar. You can also use .outerWidth() and .innerWidth() to include padding/border or just padding, respectively.
From your code, you've already changed the original dimensions of the image by using inline styles. Instead, save the image dimensions, change the image to 200 x 300px in jQuery, do what you want to it, then change it back to original dimensions:
var originalWidth = $("#bigImg").width();
var originalHeight = $("#bigImg").height();
$("#bigImg").css({
width: '200px',
height: '300px'
});
//Do whatever you meant to do here, the when you're finished...
$("#bigImg").animate({
width: originalWidth,
height: originalHeight,
},500);
jQuery documentation:
http://api.jquery.com/animate/ or http://api.jquery.com/category/dimensions/

Categories

Resources