Rotating HTML elements (by an arbitrary amount) cross browser
There are lots of articles about rotating objects, but for some reason none of them seem to have all the pitfalls. I thought I'd try and write everything I've found down.
Here are the key points:
- IE7/8 won't understand the CSS3's transform, so you'll have to generate an image transform matrix here.
- IE7/8's point of origin for the rotation is at the top left rather than the center so you'll be doing some maths to calculate the new top left position.
- IE7/8 changes the width / height of the rotated element. You'll have to store the actual width / height somewhere to use it to shift the element's point of origin.
- IE8 rotates the element, but not always the elements contained within it. You'll have to rotate those as well!
- When using jQuery, the position() method returns the top left of the new bounding box area where as the css() method will return the actual top/left position of the rotated element.
Here's the CSS / calculations for doing the actual rotation. (I've used javascript to do calculations)
Everything but IE7/8
degrees // degrees to rotate
The CSS
transform: rotate(degrees)
-ms-transform: rotate(degrees) /* IE 9 */
-moz-transform: rotate(degrees) /* Firefox */
-webkit-transform: rotate(degrees) /* Safari and Chrome */
-o-transform: rotate(degrees) /* Opera */
IE7/IE8
degrees // degrees to rotate
var radians = degrees * (Math.PI * 2 / 360);
var costheta = Math.cos(radians);
var sintheta = Math.sin(radians);
The CSS (for the rotation)
sizingMethod:auto expand;
progid:DXImageTransform.Microsoft.Matrix("M11=cost
heta,M12=-sintheta,M21=sintheta,M22=costheta);
ew // element width
eh // element height
var x1 = -ew / 2,
x2 = ew / 2,
x3 = ew / 2,
x4 = -ew / 2,
y1 = eh / 2,
y2 = eh / 2,
y3 = -eh / 2,
y4 = -eh / 2;
var x11 = x1 * costheta + y1 * sintheta,
y11 = -x1 * sintheta + y1 * costheta,
x21 = x2 * costheta + y2 * sintheta,
y21 = -x2 sintheta + y2 * costheta,
x31 = x3 * costheta + y3 * sintheta,
y31 = -x3 * sintheta + y3 * costheta,
x41 = x4 * costheta + y4 * sintheta,
y41 = -x4 * sintheta + y4 * costheta;
var x_min = Math.min(x11, x21, x31, x41) + ew / 2,
x_max = Math.max(x11, x21, x31, x41) + ew / 2;
var y_min = Math.min(y11, y21, y31, y41) + eh / 2;
y_max = Math.max(y11, y21, y31, y41) + eh / 2;
The CSS (for shifting the point of origin)
left: x_min;
top: y_min;