I currently have a page where I have fixed-size divs that load pages as a user scrolls down (similar to Infinite Scroll) and am currently working on functionality to have the loaded images and containers dynamically resize along with the browser window. My current issue is that I'm currently using $(window).width and $(window).height, which naturally causes the images to resize to the window width.
I was wondering what I can set maxWidth and maxHeight to so that the images don't get resized any greater than their original size? I've been using $(window) just to test the function, but I basically don't want the images to become any larger than their original size. I've tried $(this), but it causes the ratio to be equal to 1, resulting in no resize.
$(window).resize(function () {
imageResize();
});
function imageResize() {
$(".added").each(function () {
var maxWidth = $(window).width();
var maxHeight = $(window).height();
var ratio = 0;
var width = $(this).width();
var height = $(this).height();
if (width > maxWidth) {
ratio = (maxWidth / width);
$(this).width(maxWidth);
$(this).height(height * ratio);
$(this).parent().height(height * ratio);
$(this).parent().width(maxWidth);
} else {
ratio = (maxWidth / width);
$(this).width(maxWidth);
$(this).height(height * ratio);
$(this).parent().height(height * ratio);
$(this).parent().width(maxWidth);
}
});
}
You want to set the max-height and max-width properties to the values you said, this will not force the image to grow further than their original height or width and will minimize it if it is larger.
Use:
$("#imageId").attr("max-width",maxWidth);
$("#imageId").attr("max-height",maxHeight);
I would change the style so:
($this).style.maxWidth = maxWidth;
Related
When i run my application it gives me several errors:
the first one is:
SyntaxError: class is a reserved identifier in the class thumbnail
code:
const MAXHEIGHT = 170;
const MAXWIDTH = 320;
import {Subcategory} from './subcategory'
//import {Category} from './category'
import {bootstrap} from 'angular2/platform/browser'
class Thumbnail {
width: number;
height: number;
constructor(element: HTMLImageElement) {
this.height = element.height;
this.width = element.width;
}
resize(oImage: HTMLImageElement) {
var maxWidth = 100; // Max width for the image
var maxHeight = 100; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = oImage.width; // Current image width
var height = oImage.height; // Current image height
// Check if the current width is larger than the max
if (oImage.width > MAXWIDTH) {
ratio = MAXWIDTH / width; // get ratio for scaling image
oImage.width=MAXWIDTH; // Set new width
oImage.height=height * ratio; // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
}
// Check if current height is larger than max
if (height > MAXHEIGHT) {
ratio = MAXHEIGHT / height; // get ratio for scaling image
oImage.height= MAXHEIGHT; // Set new height
oImage.width= width * ratio; // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
height = height * ratio; // Reset height to match scaled image
}
// Check if current height is smaller than max
if (height < MAXHEIGHT) {
ratio = MAXHEIGHT / height; // get ratio for scaling image
oImage.height = MAXHEIGHT; // Set new height
oImage.width = width * ratio; // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
height = height * ratio; // Reset height to match scaled image
}
// Check if the current width is smaller than the max
if (oImage.width < MAXWIDTH) {
ratio = MAXWIDTH / width; // get ratio for scaling image
oImage.width = MAXWIDTH; // Set new width
oImage.height = height * ratio; // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
}
document.body.appendChild(oImage);
console.log(oImage.height);
console.log(oImage.width);
}
};
window.onload = () => {
var oImage = new Image();
var oImage2 = new Image();
// var category = new Category(1, "string");
var subcategory = new Subcategory("teste",1,2);
oImage.src = 'AngularJS.png';
oImage.setAttribute('class','img-responsive');
oImage2.src = 'ts.jpg';
var thumbnail = new Thumbnail(oImage);
var thumbnail2 = new Thumbnail(oImage2);
thumbnail.resize(oImage);
thumbnail2.resize(oImage2);
console.log(oImage.height);
console.log(oImage.width);
};
The second error is:
GET http://localhost:51580/app
301 Moved Permanently
The configuration of angular is:
<script>
System.config({
packages: {
TypeScriptHTMLApp1: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app')
.then(null, console.error.bind(console));
</script>
I already tried to create a folder named app and moved the file for that folder but the error persists. I need help with this, I lost several hours and can't resolve anything. I attach one image with the file structure and another one with the firebug errors. Thanks in advance.
as suggested by #Eric in comment
Classes aren't supported in Firefox version < 45 according to this article
. instead try same use case in the chrome.
posted as answer may helpful to someone.
I want .container's height to be set dynamically to <body>'s width and its height to <body>'s width, and it should change when the window is resized.
I want this because I'm trying to make a CSS only horizontally scrolling page by rotating the `.container' -90 degrees and its contents 90 degrees a la http://jsfiddle.net/3cetk351/.
The container currently has 100% height & width but once it's rotated via CSS, it retains its inherited dimensions and does not stretch to browser window size which I suppose is only logical.
I don't know much of javascript other than to change values in jquery plugins but I assume it's possible using js to dynamically alter .container's height and width to <body>'s computed width and height respectively.
jsfiddle: http://jsfiddle.net/jklm313/ZaLHM/
Is this the kind of thing you're after?
var supportsOrientationChange = 'onorientationchange' in window, orientationEvent = supportsOrientationChange ? 'orientationchange' : 'resize';
var $containment = document.getElementsByClassName('containment')[0];
$containment.style.width = window.innerHeight + 'px';
$containment.style.height = window.innerWidth + 'px';
window.addEventListener(orientationEvent, function() {
$containment.style.width = window.innerHeight + 'px';
$containment.style.height = window.innerWidth + 'px';
}, false);
Here's a fork of your pen here: http://codepen.io/stowball/pen/AIbHn
I'm writing a little script that allows the user to move and resize a div. I need to keep the aspect ratio and my logic doesn't work.
function resizing() {
var currentHeight = elmnt.offsetHeight;
var currentWidth = elmnt.offsetWidth;
var newHeight = currentHeight + (event.pageY - currentY);
var newWidth = currentWidth + (event.pageX - currentX);
var ratio = currentWidth / currentHeight;
if(ratio < 1) {
newwidth = parseInt(newHeight * ratio);
}
else {
newheight = parseInt(newWidth / ratio);
}
elmnt.style.height = newHeight + "px";
elmnt.style.width = newWidth + "px";
currentY = event.pageY;
currentX = event.pageX;
}
The script kind of works. But unfortunately it doesn't keep the aspect ratio completely correct. Sometimes, when I resize horizontyl only, the old height remains the same, sometimes it works, but one length gets resized with a little offset.
When I resize up and down and up and down again, the lengths gets more and more equal and when it is a proper square, everything is right.
Hwo can I fix my problems? Where is my fallacy?!
Your ratio is wrong I think.
You need to calculate this by taking the old width and dividing by the new width, or old height / new height.
e.g.
var ratio = newWidth / currentWidth;
newHeight = currentHeight * ratio;
Change it about if it is the height that is changing.
I could fiy it.
THANK YOU VERY MUCH!
My problem was that I first, had to track of which axis has more change. The second problem, which I didn't recognized was, that I had BIG problems with rounding issues.
When setting the css size using jQuery, it rounds. And I took the height for ratio calculations every single event.
That means that the inaccuracy was getting more and more bad.
Now I took this into account and figured out a way to get this working very good.
I now do this directly onclick and just update them instead of getting from the element:
currentHeight = $("#dragger").height();
currentWidth = $("#dragger").width();
So thanks again for your help! Here is my final result:
http://jsfiddle.net/julian_weinert/xUAZ5/30/
You have to do this, get the min scale (ratio). The code below is a part of my PHP script, but easily translated to JS. $iSrc = Source and $iDest is destination MAX width/height.
Your problem is you don't get the right ratio. The first line to define the ratio is where your problem will be solved. It gets the lowest ratio of the width or height. You just do width/height and forget height/width. That's why vertical scaling is not correct.
$scale = min($iDestWidth/$iSrcWidth, $iDestHeight/$iSrcHeight);
if($scale >= 1){
$iDestHeight = $iSrcHeight;
$iDestWidth = $iSrcWidth;
}else{
$iDestWidth = floor($scale*$iSrcWidth);
$iDestHeight = floor($scale*$iSrcHeight);
}
replace your if(ratio < 1) block with the following. offsetx and offsety relate to your (event.pageX - currentX) and (event.pageY - currentY):
if (Math.abs(offsetx) > Math.abs(offsety)) {
ratio = currentHeight/currentWidth;
newHeight = currentHeight + (offsetx * ratio);
newWidth = currentWidth + offsetx;
} else {
ratio = currentWidth/currentHeight;
newHeight = currentHeight + offsety;
newWidth = currentWidth + (offsety * ratio);
}
here is a quick jsfiddle of the whole thing in action: http://jsfiddle.net/8TWRV/
So i have a gallery where most my images are currently controlled 100% by CSS. However, in setting min-height: 100%; on my images, i cause some to stretch. I don't have too many problematic photos, but it's out of my control what the user will upload.
Is there anyway with jQuery i can get image height and check if it's meeting a requirement, and if not, somehow increase the image width in order to meet the height requirement but keep things all in ratio? So i therefore avoid causing any distortion but keep the gallery neat by having divs without gaps.
Note: The image provided is what happens when i remove my min-height: 100%; so that you can see my issue.
Update - - - - -
I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?
I simply tweaked the code ever so slightly, now if an image doesn't meet the minHeight required it will resize the image in proportion so until the minHeight is then reached. Seems work fine for me in testing.
**Update Final *********
After playing around i took a small snippit from the thumb script, just the part where it absolutely positions the images within the container.
$(window).load(function() {
$('.thumbnail img').each(function() {
var maxWidth = 320; // Max width for the image
var minHeight = 270; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
if(width > maxWidth){
ratio = maxWidth / width; // get ratio for scaling image
$(this).css("width", maxWidth); // Set new width
$(this).css("height", height * ratio); // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
}
// Check if current height is larger than max
if(height < minHeight){
ratio = minHeight / height; // get ratio for scaling image
$(this).css("height", minHeight); // Set new height
$(this).css("width", width * ratio); // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
}
var $img = $(this),
css = {
position: 'absolute',
marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
left: '50%',
top: '50%',
marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
};
$img.css( css );
});
});
This loops through all my thumbnails, resizes them accordingly. So if the minimum height is not met, the image will be scaled up until the height fits my thumbnail container. Then the bottom part will take take each image, absolutely position it, and take the width and height and divide by 2, in order to work out how much to minus off on the margins to center the image. I'm still tweaking this, but seems to work well for me at the moment. I hope this helps someone else.
Alternatively
Anyone with a similar issue i found this: http://joanpiedra.com/jquery/thumbs/ I had begun writing my own to do exactly this, but im going to look into how well this works and adapt it as needed.
I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?
Updated question with my findings
$(window).load(function() {
$('.image-gallery-item-image-link img').each(function() {
var maxWidth = 320; // Max width for the image
var minHeight = 270; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
if(width > maxWidth){
ratio = maxWidth / width; // get ratio for scaling image
$(this).css("width", maxWidth); // Set new width
$(this).css("height", height * ratio); // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
}
// Check if current height is larger than max
if(height < minHeight){
ratio = minHeight / height; // get ratio for scaling image
$(this).css("height", minHeight); // Set new height
$(this).css("width", width * ratio); // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
}
var $img = $(this),
css = {
position: 'absolute',
marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
left: '50%',
top: '50%',
marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
};
$img.css( css );
});
});
well, if keeping the entire picture visible isn't necessary(e.g. thumbnails in a gallery), you could accomplish this with css only. it seems you have landscape type photos.
html
<div class="img-container">
<img src="path/to/img.png" alt="">
</div>
css:
div > img {
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width:100%;
height:100%;
}
jquery:
$(document).ready(function(){
$(".imgcontainer > img").each(function(){
var thisimg = "url("+$(this).attr('src')+")";
$(this).css({'background-image': thisimg });
$(this).attr('src', '');
});
});
Whose aspect ratio you are talking about ? aspect ratio of your gallery or the aspect ratio of the image ? You can't keep an image in correct aspect ratio by changing one dimension only (here height). In order to keep aspect ratio, you must change both the height and width of the image. Any way if you want try this :
var img = document.getElementById('imageid');
var width = img.clientWidth;
var height = img.clientHeight;
if(width >height)
$(img).attr('style',"width=100%");
else
$(img).attr('style',"height=100%");
What I am trying to do is that, set the css of the largest dimension to 100%. It'll do the trick.
So, I realize this question asked a while ago. But I've since found a sweet css only way to maintain the aspect ratio of an element, fluidly. Try it out:
#targetElement {
max-width: 100%;
}
#targetElement:after {
content: '';
width: 100%;
padding-bottom: <aspect-ratio>%; // where (height / width)*100 = <aspect-ratio>
}
Yeah, so I use this trick all the time now, and it's definitely more performant and less verbose than using javascript, or even less efficient, JQuery. Hope this helps somebody somewhere! If you're a LESS person, I have a mixin Gist on Github that does this -- that's how often I use it! It lives here: Sweet AR trick.
Looks like I haven’t explained myself well. I do apologize for that.
I have edited this question to make it more clear.
The scenario
We have a website that doesn’t host the images. What it does is a reference to an image in other server.
The plan
Resize images keeping proportions.
Center resized images.
Flexible so it can fit in several sizes.
The bug
My code works as intended, however there is a Bug that only happens sometimes.
If you go to the search page of the website, and swap between page 1, 2, 3 and 4 a couple of times, you will notice that sometimes the images are good… other times they appear aligned left, and do not take up the full container area.
The links
The full website (in beta)
The JavaScript File
The jQuery plugin that helped me (jThumb)
The plan (detailed version)
Let’s say that the image is 600x400 pixels (remember they are not hosted on this server), and with jQuery and CSS, I want to resize the image (keeping proportions) in to a container of 310x200 pixels.
The other challenge is to center the image.
All this has to be flexible because there are several different containers sizes in the website.
What I have done so far (you can find this in the link above)
To resize the image I'm doing:
var img = new Image();
img.src = $(this).attr("src");
var width = $(this).css('width');
var height = $(this).css('height');
var photoAspectRatio = img.width / img.height;
var canvasAspectRatio = width.replace("px", "") / height.replace("px", "");
if (photoAspectRatio < canvasAspectRatio) {
$(this).css('width', width);
$(this).css('height', 'auto');
var intHeight = height.replace("px", ""); //tirar o PX
$(this).css('marginTop', (-Math.floor(intHeight / 2)));
}
else {
$(this).css('width', 'auto');
$(this).css('height', height);
}
$(this).wrap('<div class="thumb-img" style="width:' + width + ' ;height:' + height + ';"><div class="thumb-inner">' + '</div></div>');
To center the image I’m doing:
jQuery(this).css('position','absolute');
jQuery(this).left( '-' + ( parseInt( $(this).width() ) / 2 ) + 'px' );
jQuery(this).top( '-' + ( parseInt( $(this).height() ) / 2 ) + 'px' );
jQuery(this).css('margin-left', '50%' );
jQuery(this).css('margin-top', '50%');
There's a far simpler solution to determine how to resize and position the image. It will work with all image and container sizes.
var canvasWidth = parseInt(width);
var canvasHeight = parseInt(height);
var minRatio = Math.min(canvasWidth / img.width, canvasHeight / img.height);
var newImgWidth = minRatio * img.width;
var newImgHeight = minRatio * img.height;
var newImgX = (canvasWidth - newImgWidth) / 2;
var newImgY = (canvasHeight - newImgHeight) / 2;
Now just position the image using newImgX, newImgY, and resize it to newImgWidth, newImageHeight.
This is probably a race condition. You are setting the img src and then immediately trying to get its width and height attributes. But there is no guarantee that the web browser has downloaded the image or pulled it from the browser cache yet, and if it hasn't, your code will lead to unexpected results.
You need to do something like this:
var img = new Image();
var $thumb = $(this);
img.load(function() {
/* .....[image calculation and resize logic]..... */
});
img.src = $thumb.attr("src");
Note that the order of the above statements is very important -- you must attach the img.load event handler first, then assign the img.src second. If you do it in the other order, you will end up with an opposite race condition (the image may already be loaded after the img.src assignment, in which case the event handler will not be called in all browsers -- by setting the event handler first you ensure that it will be called after the img.src assignment even if the image is already loaded).
Also, note the $thumb definition at the top. This is because "this", inside the img.load function, will be a reference to the new "img", not the thumbnail element. So your logic will have to reference "$thumb" for the DOM element and "this" (or "img") for the in-memory image.
Also, for the actual logic take a look at the answer "Scott S" provided above. His suggestion looks simpler than what you have.
It's not clear from your question, but I'm assuming one your issues is the left-align of the images in the table at the bottom half of your front page at http://www.algarvehouses.com.
The issue here is not your jQuery code, rather it is your CSS.
add a text-align: center to your thumb-inner class. Then make sure that rule is loaded AFTER the "table.dlRandom img, ..." rule - or remove the display:block from that rule. That should center those images.
Generally though - to scale the image, your logic looks correct up to the point of the div. Don't quite understand that logic. You don't need to set the auto size though, just restrain the dimension that is required.
One tangential tip - in the code above you reference $(this) no less than 16 times. Do this at the top of the function, and use it from there on:
var $this = $(this);
I really didn't get your question but this maybe be help you.
function resizer(imgCls, maxWidth, maxHeight) {
var img = $('img'), imgWidth, imgHeight;
img.each(function () {
imgWidth = this.width;
imgHeight = this.height;
if (imgWidth > maxWidth || imgHeight > maxHeight) {
var widthFact = maxWidth / imgWidth;
var heightFact = maxHeight / imgHeight;
var chooseFact = (widthFact > heightFact) ? heightFact : widthFact;
imgWidth = imgWidth * chooseFact;
imgHeight = imgHeight * chooseFact;
}
})
}
this code gets the images matches the provided className and looks your arguments. pass maxWidth to your maxWidth value such as 300 px, and pass maxHeight to your images maxHeight such as 300.
then the function will loop for every image and checks its width and height. If its width or height is larger than your max values then it will be resized by keeping the aspect ratio.
Please let you free to ask more question about the issue and please be more clear.
This script will shrinks, and align image depending of their orientation. Image is rounded with div ho has fixed width and hight, and also a style set to overflow:hidden. The script actual recognize the image orientation and ad to image a margin-left or margin-top in minus atribute to style depending of a image vertical or horizontal orientation.
CSS:
<style type="text/css">
.thumb {
width:160px;
height:160px;
overflow:hidden;
}
</style>
jquery with javascript:
window.onload = function() {
var images = $(".image_center");
for(i=0; i<images.length; i++)
images[i].onload = centerImage(images[i]);
function centerImage(img) {
if (img.width > img.height ) {
var y = 160;
var x = img.width/img.height*y;
var marx = (x-y)/2;
img.style.height = y+"px";
img.style.marginLeft = -(marx) + "px";
}
if (img.width < img.height ) {
var x = 160;
var y = img.height/img.width*x;
var mary = (y-x)/2;
img.style.width = x+"px";
img.style.marginTop = -(mary) + "px";
}
}
}
HTML:
<div class="thumb"><img class="image_center" src="sa.jpg" alt="#" /></div>
<div class="thumb"><img class="image_center" src="sb.jpg" alt="#" /></div>
You can see demo here: Link
Another useful plugin which achieves this is jQuery Center Image which supports two modes. One to fill the entire space by cropping and resizing the image and another which emulates max-width/max-height to resize to fit within the space.