问题
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?!
回答1:
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.
回答2:
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/
回答3:
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);
}
回答4:
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/
来源:https://stackoverflow.com/questions/14611736/javascript-div-resizing-with-aspect-ratio