2010-04-20 13 views
29

Estoy tratando de averiguar cómo rotar un solo objeto en un lienzo html 5.¿Cómo giro un único objeto en un lienzo html 5?

Por ejemplo: http://screencast.com/t/NTQ5M2E3Mzct - Quiero que cada una de esas tarjetas se gire en un grado diferente.

Hasta ahora, todo lo que he visto son artículos y ejemplos que demuestran formas de rotar todo el lienzo. En este momento, supongo que tendré que rotar el lienzo, dibujar una imagen y luego girar el lienzo de regreso a su posición original antes de dibujar la segunda imagen. Si ese es el caso, ¡házmelo saber! Solo tengo la sensación de que hay otra manera.

¿Alguien tiene alguna idea?

¡Gracias de antemano!

Respuesta

35

Desafortunadamente, en el elemento canvas de HTML5 no puede rotar elementos individuales.

La animación funciona como dibujar en MS Paint: Dibuja algo, crea una pantalla ... usa el borrador para eliminar algunas cosas, dibuja algo diferente, crea una pantalla ... Dibuja algo más encima, crea una pantalla ... etc. etc.

Si tiene un elemento existente en el lienzo, tendrá que borrarlo (use ctx.fillRect() o por ejemplo), y luego dibuje el objeto girado.

Si no está seguro de cómo se gire mientras se dibuja en el primer lugar:

ctx.save(); 
ctx.rotate(0.17); 
// draw your object 
ctx.restore(); 
+0

Bummer! ¡Supongo que tendrá que hacerlo, Artiom! ¡Gracias por la respuesta! – Kappers

+3

Sí, lo sé ... cuando escribo animaciones más complejas, este tema se vuelve aún más grande, porque tienes que volver a dibujar todo el lienzo desde cero con cada fotograma :) –

+2

Sugiere que reemplaces 'fillRect()' con 'clearRect()' en tu responder. – Phrogz

15

Para girar un objeto individual tiene que establecer la matriz de transformación. Esto es muy simple:

<body> 
    <canvas width="1280" height="720" id="pageCanvas"> 
     You do not have a canvas enabled browser 
    </canvas> 
    <script> 
     var context = document.getElementById('pageCanvas').getContext('2d'); 
     var angle = 0; 
     function convertToRadians(degree) { 
      return degree*(Math.PI/180); 
     } 

     function incrementAngle() { 
      angle++; 
      if(angle > 360) { 
       angle = 0; 
      } 
     } 

     function drawRandomlyColoredRectangle() { 
      <!-- clear the drawing surface --> 
      context.clearRect(0,0,1280,720); 
      <!-- you can also stroke a rect, the operations need to happen in order --> 
      incrementAngle(); 
      context.save();     
      context.lineWidth = 10; 
      context.translate(200,200); 
      context.rotate(convertToRadians(angle)); 
      <!-- set the fill style --> 
      context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16); 
      context.fillRect(-25,-25,50,50); 
      context.strokeRect(-25,-25,50,50);     
      context.restore(); 
     } 

     setInterval(drawRandomlyColoredRectangle, 20); 
    </script> 
</body> 
3

Este html/javascript código podría arrojar alguna luz sobre el asunto:

<!DOCTYPE html> 
<html> 
<body> 

<canvas id="myCanvas" width="233" height="233" style="border:1px solid #d3d3d3;"> 
your browser does not support the canvas tag </canvas> 

<script type="text/javascript"> 

var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d"); 
var canvasWidth=233; 
var canvasHeight=233; 
var rectWidth=100; 
var rectHeight=150; 
var x=30; 
var y=30; 
var translateX= x+(rectWidth/2); 
var translateY= y+(rectHeight/2); 

ctx.fillRect(x,y,rectWidth,rectHeight); 

ctx.translate(translateX,translateY); 
ctx.rotate(5*Math.PI/64); /* just a random rotate number */ 
ctx.translate(-translateX,-translateY); 
ctx.fillRect(x,y,rectWidth,rectHeight); 


</script> 

</body> 
</html> 

me resulta útil para ver los cálculos relacionados con la rotación, espero que esto era útil igualmente.

46

Me encontré con el mismo problema en un proyecto reciente (donde pateé extraterrestres giratorios por todas partes). Acabo de utilizar esta humilde función que hace lo mismo y se puede usar de la misma manera que ctx.rotate, pero se puede pasar un ángulo. Funciona bien para mí

function drawImageRot(img,x,y,width,height,deg){ 

    //Convert degrees to radian 
    var rad = deg * Math.PI/180; 

    //Set the origin to the center of the image 
    ctx.translate(x + width/2, y + height/2); 

    //Rotate the canvas around the origin 
    ctx.rotate(rad); 

    //draw the image  
    ctx.drawImage(img,width/2 * (-1),height/2 * (-1),width,height); 

    //reset the canvas 
    ctx.rotate(rad * (-1)); 
    ctx.translate((x + width/2) * (-1), (y + height/2) * (-1)); 
} 

Yay, mi primera respuesta!

+1

Esto debería estar incorporado en el lienzo. Funciona perfectamente. ¡Gracias por compartir! – Synexis

+2

Éste debería ser ahora marcado como respuesta realmente. Lástima que SO no permita elegir una respuesta más nueva como respuesta en una fecha posterior. Tal vez eso es algo que debe considerarse ya que la tecnología cambia y las personas obtienen respuestas nuevas más correctas. – raddevus

+0

¿No tendrá el potencial de causar la degradación del fondo si lo gira una y otra vez? – v010dya

6

Básicamente, para hacer que un objeto gira correctamente sin tener otra forma giratoria alrededor, es necesario:

  1. guardar el contexto: ctx.save()
  2. mover el punto de pivote hasta la posición deseada: ctx.translate (200, 200);
  3. dibujar la forma, sprite, lo que sea: ctx.draw ...
  4. restablecer el pivote: ctx.translate (-200, -200);
  5. restaurar el contexto a su estado original: ctx.restore();

Formas extraidas de la lista mencionada anteriormente no se verán afectadas. Espero que ayude.

+1

y ¿qué ocurre con la rotación? Nunca lo mencionaste –

+0

esto era justo lo que necesitaba saber, ¡gracias! tal vez si hubieras puesto la parte de rotación, hubieras obtenido muchos más votos. – Samuel

2
<!DOCTYPE html> 
<html> 
<body> 

<canvas id="myCanvas" width="500" height="450" style="border:1px solid #d3d3d3;"> 
</canvas> 

<Button id = "right" onclick = "rotateRight()">Right</option> 
<Button id = "left" onclick = "rotateLeft()">Left</option> 
<script src = "zoom.js"> 

</script> 

<script> 
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d"); 

createRect(); 

function rotateRight() 
{ 
ctx.save(); 
ctx.clearRect(0,0,500,450); 
ctx.translate(c.width/2,c.height/2); 
ctx.rotate(10*Math.PI/180); 
ctx.translate(-c.width/2,-c.height/2); 
createRect(); 

} 

function rotateLeft() 
{ 
ctx.save(); 
ctx.clearRect(0,0,500,450); 
ctx.translate(c.width/2,c.height/2); 
ctx.rotate(-10*Math.PI/180); 
ctx.translate(-c.width/2,-c.height/2); 
createRect(); 
} 



function createRect() 
{ 
ctx.beginPath(); 
ctx.fillStyle = "#AAAA00"; 
ctx.fillRect(250,250,90,50); 
} 
</script> 

</body> 
</html> 
2

Para girar un objeto que se puede utilizar rotate() método. Aquí el ejemplo de cómo rotar un objeto rectangular a 135 grados en el sentido de las agujas del reloj.

<script> 
    var canvas = document.getElementById('Canvas01'); 
    var ctx = canvas.getContext('2d'); 

    var rectWidth = 100; 
    var rectHeight = 50; 

    //create line 
    ctx.strokeStyle= '#ccc'; 
    ctx.beginPath(); 
    ctx.moveTo(canvas.width/2, 0); 
    ctx.lineTo(canvas.width/2, canvas.height); 
    ctx.stroke(); 
    ctx.closePath(); 

    ctx.beginPath(); 
    ctx.moveTo(0, canvas.height/2); 
    ctx.lineTo(canvas.width, canvas.height/2); 
    ctx.stroke(); 
    ctx.closePath(); 

    // translate ctx to center of canvas 
    ctx.translate(canvas.width/2, canvas.height/2); 

    // rotate the rect to 135 degrees of clockwise 
    ctx.rotate((Math.PI/180)*135); 

    ctx.fillStyle = 'blue'; 
    ctx.fillRect(0, 0, rectWidth, rectHeight); 
</script> 
</body> 

Aquí la demo y se puede intentar usted mismo: http://okeschool.com/examples/canvas/html5-canvas-rotate

0

me encontré con esta pregunta porque tenía un montón de cosas en un lienzo, dibujado con líneas de lona, ​​con esmero, y luego decidió algunos de ellos debe ser rotado. No queriendo hacer todo un montón de cosas complejas, quería rotar lo que tenía. Una solución sencilla que encontré fue esto:

ctx.save(); 

ctx.translate(x+width_of_item/2,y+height_of_item/2); 
ctx.rotate(degrees*(Math.PI/180)); 
ctx.translate(-(x+width_of_item/2),-(y+height_of_item/2)); 

// THIS IS THE STUFF YOU WANT ROTATED 
// do whatever it is you need to do here, moveto and lineto is all i used 
// I would expect anything to work. use normal grid coordinates as if its a 
// normal 0,0 in the top left kind of grid 

ctx.stroke(); 
ctx.restore(); 

De todos modos - que podría no ser particularmente elegante, pero es una manera fácil de muertos para rotar un elemento en particular en su lienzo.

Look at all those rotated elements!

Cuestiones relacionadas