Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adjusting div width and height after rotated

If I have these rules:

width:50px;
height:100px;
-moz-transform: rotate(0deg)

and then an event changes the transform to:

-moz-transform: rotate(90deg)

logically, shouldn't that automatically exchange the width and the height? I need the rotate to switch width and height for accurate position detection.

Thanks,

Joe

like image 571
Joe Longstreet Avatar asked Jul 18 '10 17:07

Joe Longstreet


2 Answers

It seems like the transform is applied after everything else, so the width and height aren't updated. The best solution I can think of is to calculate the rotated dimensions yourself, using the rotation matrix:

[ cos X     -sin X ] [ width  ]
[ sin X      cos X ] [ height ]

It's straightforward to translate this into JavaScript. You need to rotate all four corners (0,0) (w,0) (0,h) (w,h) and then the rotated dimensions are the width and height of the rotated bounding rectangle.

var angle = angle_in_degrees * Math.PI / 180,
    sin   = Math.sin(angle),
    cos   = Math.cos(angle);

// (0,0) stays as (0, 0)

// (w,0) rotation
var x1 = cos * width,
    y1 = sin * width;

// (0,h) rotation
var x2 = -sin * height,
    y2 = cos * height;

// (w,h) rotation
var x3 = cos * width - sin * height,
    y3 = sin * width + cos * height;

var minX = Math.min(0, x1, x2, x3),
    maxX = Math.max(0, x1, x2, x3),
    minY = Math.min(0, y1, y2, y3),
    maxY = Math.max(0, y1, y2, y3);

var rotatedWidth  = maxX - minX,
    rotatedHeight = maxY - minY;
like image 179
casablanca Avatar answered Sep 28 '22 06:09

casablanca


Here's the most elegant JavaScript solution, that I have achieved.

// suppose, we know width, height and rotation angle (deg)
var width, height, angle;

var rad = angle * Math.PI / 180,
    sin = Math.sin(rad),
    cos = Math.cos(rad);

var newWidth  = Math.abs(width * cos) + Math.abs(height * sin),
    newHeight = Math.abs(width * sin) + Math.abs(height * cos);
like image 33
Arsen K. Avatar answered Sep 28 '22 07:09

Arsen K.