Para rotar imágenes lo más común es usar lenguaje de servidor. En PHP, por ejemplo, lo normal sería usar la función
imagerotate de la librería GD. En javascript, hasta que se extendió el soporte canvas a casi todos los navegadores, había un camino tortuoso que consistía en crear capas que mostraran sólo un pixel de la imagen en la posición que correspondia a la rotación que queríamos lograr, la cual calculábamos con un poco de trigonometría. Sin embargo esto era inviable para imágenes de tamaño mediano, ya que, como estábamos obligados a crear un bucle con tantas iteraciones como pixeles hubiese en la imagen a rotar, el proceso se hacía muy lento y/o consumía mucha memoria.
Afortunadamente canvas ya es soportado por todos los navegadores modernos excepto Explorer. No obstante esto, Explorer cuenta con un filtro propietario que nos ayudará en nuestra tarea.
Este es un ejemplo de lo que podremos lograr utilizando la función que presentamos más abajo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>test</title>
<script>
function rotar(obj,angulo){
if (angulo >= 0) {
var rotation = Math.PI * angulo / 180;
} else {
var rotation = Math.PI * (360+angulo) / 180;
}
var costheta = Math.cos(rotation);
var sintheta = Math.sin(rotation);
if (document.createElement("canvas").getContext) {
/* ---- canvas ---- */
var c=document.createElement('canvas');
c.width = Math.abs(costheta*obj.width) + Math.abs(sintheta*obj.height);
c.style.width = c.width+'px';
c.height = Math.abs(costheta*obj.height) + Math.abs(sintheta*obj.width);
c.style.height=c.height+'px';
c.id=obj.id;
c.style.position='absolute';
var ctx=c.getContext('2d');
ctx.save();
if (rotation <= Math.PI/2) {
ctx.translate(sintheta*obj.height,0);
} else if (rotation <= Math.PI) {
ctx.translate(c.width,-costheta*obj.height);
} else if (rotation <= 1.5*Math.PI) {
ctx.translate(-costheta*obj.width,c.height);
} else {
ctx.translate(0,-sintheta*obj.width);
}
ctx.rotate(rotation);
ctx.drawImage(obj, 0, 0, obj.width, obj.height);
obj.parentNode.replaceChild(c,obj);
ctx.restore();
}else{
/* ---- DXImageTransform ---- */
obj.style.position='absolute';
obj.style.filter="progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand')";
obj.filters.item(0).M11 = costheta;
obj.filters.item(0).M12 = -sintheta;
obj.filters.item(0).M21 = sintheta;
obj.filters.item(0).M22 = costheta;
}
}
window.onload=function(){
rotar(document.getElementById('pp'),60);
}
</script>
</head>
<body>
<img src="1.jpg" width="180" height="127" />
<div id="ll" style="position:relative; "><img id="pp" src="1.jpg" width="180" height="127" /></div>
</body>
</html>