2011-06-01 13 views
10

Estoy dibujando una imagen en HTML 5 utilizando lienzo en JavaScript. Necesito dibujarlo en un ángulo girado. Sé que esto se puede hacer aplicando la función rotar (ángulo) usando el contexto del lienzo. Pero necesito hacer esto sin rotar el lienzo en sí.Imagen de dibujo en Lienzo en un ángulo SIN rotar el lienzo

Amablemente sugiera un posible enfoque para esto si es posible.

Respuesta

6

En realidad se puede dibujar lo que desea girar en un lienzo fuera de la pantalla y dibujar que en su lienzo principal. Tomé prestado este código desde un Google IO Discusión:

rotateAndCache = function(image,angle) { 
    var offscreenCanvas = document.createElement('canvas'); 
    var offscreenCtx = offscreenCanvas.getContext('2d'); 

    var size = Math.max(image.width, image.height); 
    offscreenCanvas.width = size; 
    offscreenCanvas.height = size; 

    offscreenCtx.translate(size/2, size/2); 
    offscreenCtx.rotate(angle + Math.PI/2); 
    offscreenCtx.drawImage(image, -(image.width/2), -(image.height/2)); 

    return offscreenCanvas; 
} 

continuación, almacenar en caché con:

rotobj = rotateAndCache(myimg,myangle) 

y en su drawcode:

mycontext.drawImage(rotobj,x_coord,y_coord) 

esto sólo es útil si tiene un objeto que gira un ángulo solo una vez y, posteriormente, solo está sujeto a transformaciones.

+0

Gracias PeterT. Eso casi encaja en la factura de lo que estaba buscando. Gracias de nuevo. – Vinayak

+0

¿Alguna posibilidad de tener el enlace a esa charla? – Alexander

+1

@Alexander realmente lo hago: http://www.google.com/events/io/2011/sessions/super-browser-2-turbo-hd-remix-introduction-to-html5-game-development.html the Video está en http://www.youtube.com/watch?v=yEocRtn_j9s – PeterT

0

Eso no es posible y probablemente no lo necesite. Prueba esto:

context.save() // Save current state (includes transformations) 
context.rotate() 
... draw image ... 
context.restore() // Restore state 
+0

¿Hay una manera similar a la escala de la imagen? – Kantesh

3

Cuando se aplica la transformación en la lona no rotar lienzo. simplemente diga que todo lo que va a dibujar se transformará de una manera particular. Si desea evitar que la transformación afecte a otros comandos, utilice los métodos save() y restore(). Permiten guardar y restaurar la configuración del lienzo.

ctx.save(); 
ctx.rotate(30); 
ctx.drawImage(); 
ctx.restore(); 
+0

¿Hay alguna manera similar de escalar la imagen? – Kantesh

+0

Sí, 'scale' en lugar de' rotate'. Y dos parámetros, factores de escala horizontal y vertical. – bjornd

1

He votado @ PeterT-- buen fragmento y funciona bien-- ¡gracias por eso! Tuve que hacer 3 pequeños cambios para que esto funcionara para mí:

1. el máximo de ancho y alto no es suficiente: si piensas en rotar un cuadrado, necesitas un círculo cuyo diámetro es la diagonal del cuadrado (var diam).
2. el lienzo debe ser traducido de nuevo (o use guardar/restaurar).
3. las coordenadas del objeto xey deben ajustarse para el tamaño del lienzo.

así que terminé con:

rotateAndCache = function(image,angle) { 
     var offscreenCanvas = document.createElement('canvas'); 
     var offscreenCtx = offscreenCanvas.getContext('2d'); 

     var size = Math.max(image.width, image.height); 
     var diam = 2*((size/2)*Math.sqrt(2));     // needs to be saved 
     offscreenCanvas.width = diam; 
     offscreenCanvas.height = diam; 

     offscreenCtx.translate(diam/2, diam/2); 
     offscreenCtx.rotate(angle); 
     offscreenCtx.drawImage(image, -(image.width/2), -(image.height/2)); 
     offscreenCtx.translate(-diam/2, -diam/2); 

     return offscreenCanvas; 
} 


y la posición ajustada empate (necesita ser guardado en rotateAndCache):
mycontext.drawImage(rotobj,x-(diam-width)/2,y-(diam-height)/2);

+0

si quiere ser preciso, necesita un círculo con un diámetro que sea equivalente a la diagonal del rectángulo, por lo que sería 'var diam = Math.sqrt (image.width * image.width + image.height * image .height); 'pero sí, entiendo tu punto. – PeterT

+0

Sí, la dimensión más grande es confusa, quise decir diagonal. El código debería hacer eso (es un triángulo rectángulo de 1 radical y 2) – dhc

+0

Pero esa es la diagonal de un cuadrado con una longitud de 'max (image.width, image.height)' en todos los lados, ¿no es así? Que puede o no ser un poco más grande que el de un rectángulo con lados desiguales (al menos no es más pequeño, por lo que no causará errores). – PeterT

Cuestiones relacionadas