Transformaciones a medida

facebook-svg gplus-svg twitter-svg

Además de mover con tanslate(), redimensionar con scale() y girar con rotate(), el <canvas> de HTML5 dispone de dos métodos que nos permiten hacer transformaciones a medida: transform() y setTransform().

Método JavaScript Descripción Defecto
translate() context.translate(x,y); Mueve el origen (0,0) del <canvas> en un punto dado (x,y). 0,0
rotate() context.rotate(ángulo); Gira los trazados posteriores un ángulo dado (en radianes). El punto alrededor del cual gira coincide con el origen del <canvas> (0,0) 0
scale() context.scale(h,v); Reduce o amplía a escala el dibujo actual.
h = horizontal; v = vertical
Valores que pueden tomar los parametros del método: 1=100%, 0.5=50%, 2=200%, etc...
1,1
transform() context.transform(a,b,c,d,e,f); Cambia los trazados posteriores, cambiando la matriz de estos. 1,0,0,1,0,0
setTransform() context.setTransform(a,b,c,d,e,f); Reinicia el canvas a los valores iniciales, antes de proceder a cambiar los trazados posteriores. 1,0,0,1,0,0

Vea la chuleta con las propiedades y metodos() de canvas.

Cada objeto en el <canvas> tiene una matriz de transformación. transform o transform
La matriz inicial ( sin transformación alguna ) tiene este aspecto: transform
El método transform() substituye la matriz actual del objeto, por otra, y toma 6 argumentos (a,b,c,d,e,f). Los 6 argumentos corresponden a los 6 primeros elementos de la matriz y representan:

a rx Redimensiona horizontalmente el dibujo. ejemplo
b sy Sesga verticalmente el dibujo ejemplo
c sx Sesga horizontalmente el dibujo ejemplo
d ry Redimensiona verticalmente el dibujo ejemplo
e mx Mueve horizontalmente el dibujo ejemplo
f my Mueve verticalmente el dibujo ejemplo

Transformar con transform()

Empezamos dibujando un cuadrado: ctx.fillRect(0,0,50,50) azul (#0000FF) que dejamos como testigo en la esquina superior izquierda. A continuación cambiamos el color, transformamos el contexto del <canvas> con ctx.transform(.7,.7,-.7,.7,125,10) y dibujamos de nuevo el mismo rectángulo.
Repetimos esta operación dos veces más, y como que las transformaciones en el canvas son cumulativas, cada vez obtenemos algo diferente.

Su navegador no soporta canvas :( 

		var canvas = document.getElementById("lienzo");
				if (canvas && canvas.getContext) {
				var ctx = canvas.getContext("2d");
				if (ctx) {
						ctx.fillStyle = "#0000FF";
						ctx.fillRect(0,0,50,50);	
						ctx.fillStyle = "#1E90FF";
						ctx.transform(.7, .7, -.7, .7, 125,10);
						ctx.fillRect(0,0,50,50);
						ctx.fillStyle = "#FF0000";
						ctx.transform(.7, .7, -.7, .7, 135,10);
						ctx.fillRect(0,0,50,50);
						ctx.fillStyle = "#FF9900";
						ctx.transform(.7, .7, -.7, .7, 145,10);
						ctx.fillRect(0,0,50,50);
				}
		}
Su navegador no soporta canvas :(

Transformar con setTransform()

A diferencia de transform(), el método setTransform() no es cumulativo, ya que vuelve a poner a cero ( set ) el contexto del <canvas>.
A continuación aprovechamos el código del ejemplo anterior con la única diferencia que utilizamos el método setTransform() en lugar de transform().
Veamos la diferencia.

Su navegador no soporta canvas :( 

		var canvas1 = document.getElementById("lienzo1");
				if (canvas1 && canvas1.getContext) {
				var ctx1 = canvas1.getContext("2d");
				if (ctx1) {
						ctx1.fillStyle = "#0000FF";
						ctx1.fillRect(0,0,50,50);	
						ctx1.fillStyle = "#1E90FF";
						ctx1.setTransform(.7, .7, -.7, .7, 125,10);
						ctx1.fillRect(0,0,50,50);
						ctx1.fillStyle = "#FF0000";
						ctx1.setTransform(.7, .7, -.7, .7, 135,10);
						ctx1.fillRect(0,0,50,50);
						ctx1.fillStyle = "#FF9900";
						ctx1.setTransform(.7, .7, -.7, .7, 145,10);
						ctx1.fillRect(0,0,50,50);
				}
		}
Su navegador no soporta canvas :(

Algunos casos prácticos

Como ya hemos visto la matriz inicial ( sin transformación alguna ) tiene este aspecto:

ctx.transform(1,0,0,1,0,0);

Para trasladar el objeto tenemos que modificar los últimos dos parámetros de la matriz de esta manera:

var x = 125; // el desplazamiento vertical
var y = 50;// el desplazamiento horizontal
//primero transformamos el contexto
ctx.transform(1,0,0,1,x,y);
//después dibujamos el objeto, un rectángulo en este caso, con las coordenadas de la esquina izquierda arriba en el origen del canvas (0,0)
ctx.fillRect(0, 0, 50, 50);

See the Pen cc8fc95b2f7972cb1017480354c72b74 by Gabi (@enxaneta) on CodePen.

Para redimensionar el objeto habrá que modificar el primero y el cuarto parámetro de la matriz de esta manera:

var rx = 2; // la escala horizontal 
var ry = .5; // la escala vertical
/*primero transformamos el contexto
en este caso la anchura del contexto aumentara a 200% de su valor inicial (rx = 2), mientras que la altura se verá reducida a un 50% (ry = .5).*/
ctx.transform(rx,0,0,ry,0,0);
//después dibujamos el objeto
ctx.fillRect(50, 120, 50, 50);

See the Pen Redimensionar con transform() by Gabi (@enxaneta) on CodePen.

Para sesgar un objeto tenemos que modificar el segundo y el tercero parámetro de la matriz de esta manera:

var sx = Math.PI/6; // la deformación horizontal: un ángulo en radianes
var sy = 0; // la deformación vertical, nula en este caso
ctx.transform(1,sx,sy,1,0,0);
//después dibujamos el objeto
ctx.fillRect(130, -20, 50, 50);

See the Pen Redimensionar con transform() by Gabi (@enxaneta) on CodePen.

Para girar un objeto con el método transform() o setTransform() tenemos que sesgarlo y redimensionarlo a la vez. Por ejemplo si queremos girarlo en un ángulo de 45°, tenemos que escribir:

var a = Math.PI/4;//el ángulo en radianes
var a_cos =  Math.cos(a);
var a_sin = Math.sin(a);
//primero transformamos el contexto
ctx.transform(a_cos, a_sin, -a_sin, a_cos, 0, 0);
//después dibujamos el objeto
ctx.fillRect(125, -80, 50, 50);

See the Pen Girar con transform() by Gabi (@enxaneta) on CodePen.