Transform: Transformaciones personalizadas

Ya has visto algunos métodos de transformación. tales como la el escalado, traslación o la rotación. Pero aún existe otro método para transformar el contexto de dibujo de forma totalmente personalizada. Es un sistema que incluye a los tres anteriores y además permite distorsionar la imagen dibujada, lo que le denomida sesgado, que no es más que un desplazamiento de algunos puntos clave del dibujo inclinando las figuras en vertical u horizontal

Son dos los métodos usados: transfrom() y setTransfrom(). La única diferencia es que el primero es acumulativo como el escalado, traslación y rotación, mientras que el segundo es absoluto.

Ambos usan seis argumentos: ex, sy, sx, ey, tx, ty.

ex, ey: son factores de escala, ex para la escala horizontal y ey opra la vertical. funcionan igual que en scale()

sx, sy: deforman la malla del canvas en horizontal (sx) y en vertical, sy. Aplicados a un rectángulo sx inclinaría los lados verticales y sy inclinaría los lados superior e inferior. Funcionan como un desplazamiento

tx, ty: trasladan el origen en horizontal y vertical, de forma similar al método translate(tx, ty).

El método setTransform() hace dos cosas: primero resetea los seis valores de la transformación a sus valores por defecto y luego aplica transform() con los valores que se le pasan como argumento.

El resetero de estos valores también se puede hacer mediante el método resetTransform(), con ello los seis valores recuperan sus valores por defectro: ex: 1, sy: 0, sx: 0, ey: 1 , tx: 0, ty: 0

En el ejemplo primero se dibuja un rectángulo rojo para usarlo como muestra y luego se aplica una transformación solo con los parámetro sx, sy (en inglés skew) y volvemos a dibujar el mismo rectángulo pero en rojo y abajo del anterior

<canvas width="600" height="300" id="mipanel" style="border: 1px solid black"></canvas>
<script> 
	var miLienzo = document.getElementById("mipanel");
	var lapiz = miLienzo.getContext("2d");
	lapiz.fillStyle="red";
	lapiz.fillRect(150, 0, 100, 50);
	lapiz.transform(1, 0.4, 0, 1, 0, 0);
	lapiz.fillStyle="blue";
	lapiz.fillRect(150, 50, 100, 50);
</script> 
Prueba este código

Usando adecuadamente este método también puedes conseguir giros. Pero tienes que actuar sobre el skew y sobre el escalado. Un poco de trigonometría (no te asustes, siempre queda el método prueba error). Imagina el canvas como una cuadrícula, bien pues el skew o distorsión es como deformar esa cuadrícula girando sus lados. Los atributos skew (sx sy) puedes verlo como el seno del ángulo de ese giro. Si utilizas dos valores iguales y opuestos consigues un giro, pero el tamaño de la imagen se sigue midiendo en horizontal y parece modificado, para mantener el tamaño debes usar el coseno de ese ángulo para el factor de escala. Míralo en el ejemplo, donde giramos un rectángulo 30º

<canvas width="600" height="300" id="mipanel" style="border: 1px solid black"></canvas>
<script> 
	var miLienzo = document.getElementById("mipanel");
	var lapiz = miLienzo.getContext("2d");
	lapiz.fillStyle="red";
	var giro = 30;
	var sen = Math.sin(giro*Math.PI/180);
	var cos = Math.cos(giro*Math.PI/180);
	lapiz.fillRect(150, 25, 100, 100); //rectágulo normal sin transformaciones    
	lapiz.transform(cos, sen, -sen, cos, 0, 0);  
	lapiz.fillStyle = "blue";
	lapiz.fillRect(150, 25, 100, 100);
</script> 
Prueba este código