web-dev-qa-db-fra.com

Comment faire pivoter un seul objet sur une toile html 5?

J'essaie de comprendre comment faire pivoter un seul objet sur une toile HTML 5. 

Par exemple: http://screencast.com/t/NTQ5M2E3Mzct - Je veux que chacune de ces cartes soit tournée à un degré différent.

Jusqu'ici, tout ce que j'ai vu sont des articles et des exemples qui illustrent les moyens de faire pivoter l'intégralité de la toile. Pour le moment, je suppose que je vais devoir faire pivoter la toile, dessiner une image, puis la faire revenir à sa position d'origine avant de dessiner la deuxième image. Si c'est le cas, faites le moi savoir! J'ai juste le sentiment qu'il existe un autre moyen.

Quelqu'un a quelquonque idée?

Merci d'avance!

31
Kappers

Malheureusement, dans l'élément de canevas HTML5, vous ne pouvez pas faire pivoter des éléments individuels. 

L'animation fonctionne comme si vous dessiniez dans MS Paint: dessinez quelque chose, créez un écran, utilisez la gomme pour supprimer des éléments, dessinez quelque chose différemment, créez un écran, etc.

Si vous avez un élément existant sur le canevas, vous devrez l’effacer (utilisez ctx.fillRect() ou clearRect() par exemple), puis dessinez l’objet pivoté.

Si vous ne savez pas comment le faire pivoter tout en dessinant:

ctx.save();
ctx.rotate(0.17);
// draw your object
ctx.restore();
37
Artiom Chilaru

J'ai rencontré le même problème dans un projet récent (où j'ai lancé des extraterrestres en rotation dans tous les sens). Je viens d'utiliser cette fonction humble qui fait la même chose et peut être utilisé de la même manière que ctx.rotate mais peut être passé d'un angle. Fonctionne bien pour moi.

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));
}

Oui, ma première réponse!

52
user1602942

Pour faire pivoter un objet individuel, vous devez définir la matrice de transformation. C'est vraiment 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();
        }

        // Ideally use getAnimationFrame but for simplicity:
        setInterval(drawRandomlyColoredRectangle, 20);
    </script>
</body>
16
Anthony W

Fondamentalement, pour faire bien tourner un objet sans avoir une autre forme en rotation, vous devez:

  1. enregistrer le contexte: ctx.save ()
  2. déplacez le point de pivotement à l'emplacement souhaité: ctx.translate (200, 200);
  3. dessinez la forme, Sprite, peu importe: ctx.draw ...
  4. réinitialiser le pivot: ctx.translate (-200, -200);
  5. restaure le contexte à son état d'origine: ctx.restore ();

Les formes dessinées en dehors de la liste mentionnée ci-dessus ne seront pas affectées. J'espère que ça aide. 

6
TTalt

Ce code html/javascript pourrait nous éclairer sur le sujet:

<!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>

Je trouve utile de voir les calculs liés à la rotation, j'espère que cela vous a été utile également.

3
turbopipp
<!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
PGB

Pour faire pivoter un objet, vous pouvez utiliser tourner() méthode. Voici l'exemple de la rotation d'un objet rectangulaire à 135 degrés dans le sens des aiguilles d'une montre .

 <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>

Ici la démo et vous pouvez essayer vous-même:  http://okeschool.com/examples/canvas/html5-canvas-rotate

2
MichaelCalvin

J'ai trouvé cette question parce que j'avais un tas de choses sur une toile, dessinées avec des lignes de toile, minutieusement, puis j'ai décidé que certaines d'entre elles devraient être tournées. Ne voulant pas refaire tout un tas de choses complexes, je voulais faire la rotation de ce que j'avais. Une solution simple que j'ai trouvée était la suivante:

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();

Quoi qu’il en soit, il n’est peut-être pas particulièrement élégant, mais c’est un moyen très facile de faire pivoter un élément particulier sur votre toile.

Regardez tous ces éléments en rotation!

0
Alexander Bunting