views:

2963

answers:

3

When you rotate an image using canvas, it'll get cut off - how do I avoid this? I already made the canvas element bigger then the image, but it's still cutting off the edges.

Example:

<html>
    <head>
     <title>test</title>
     <script type="text/javascript">
      function startup() {
       var canvas = document.getElementById('canvas');
       var ctx = canvas.getContext('2d');
       var img = new Image();
       img.src = 'player.gif';
       img.onload = function() {
        ctx.rotate(5 * Math.PI / 180);
        ctx.drawImage(img, 0, 0, 64, 120);
       }
      }
     </script>
    </head>
    <body onload='startup();'>
     <canvas id="canvas" style="position: absolute; left: 300px; top: 300px;" width="800" height="800"></canvas>
    </body>
</html>
+2  A: 

Rotation always occur around the current origin. So you might want to use translate first to translate the canvas to the position around which you want to rotate (say the center) then rotate.

e.g.

ctx.translate(85, 85);
ctx.rotate(5 * Math.PI / 180);

The canvas now rotates around (85, 85).

Vincent Ramdhanie
+3  A: 

In addition to rotating the canvas before rotating, you will need to use the "translate" again just before placing the image, like so:

ctx.translate(85, 85);
ctx.rotate(5 * Math.PI / 180);  // for 5 degrees like the example from Vincent

And then just before adding the image use translate again

ctx.translate(-85, -85);

This will move the (0,0) coordinate of ctx.drawImage(img,0,0,10,10) back to the expected 0,0 coordinate of the CANVAS.

Romansky
+2  A: 

or simply include the save and restore functions in canvas

ctx.save();
ctx.translate(85,85);
ctx.rotate(5 * Math.PI / 180);
ctx.fillRect(10,10,10,10);
ctx.restore();

If you would like to rotate around the drawn objects axis you would translate by the objects x location and y location. Then when creating the object its x location would be negative half its width and the y would be negative half its height.

Example:

Square = {
    x:10,
    y:10,
    width:10,
    height:10,
    angle:5
}
ctx.save();
ctx.translate(Square.x,Square.y);
ctx.rotate(Square.angle * Math.PI / 180);
ctx.fillRect(-Square.width/2,-Square.height/2,Square.width,Square.height);
ctx.restore();

Hope this helps someone :)