Canvas rotate from bottom center image angle?

34,605

Solution 1

First you have to translate to the point around which you would like to rotate. In this case the image dimensions are 64 x 120. To rotate around the bottom center you want to translate to 32, 120.

ctx.translate(32, 120);

That brings you to the bottom center of the image. Then rotate the canvas:

ctx.rotate(90 * Math.PI/180);

Which rotate by 90 degrees.

Then when you draw the image try this:

ctx.drawImage(img, -32, -120, 64, 120);

? Does that work?

Solution 2

The correct answer is, of course, Vincent's one.
I fumbled a bit with this rotation/translation thing, and I think my little experiments could be interesting to show:

<html>
  <head>
    <title>test</title>
    <script type="text/javascript">
    canvasW = canvasH = 800;
    imgW = imgH = 128;
    function startup() {
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      // Just to see what I do...
      ctx.strokeRect(0, 0, canvasW, canvasH);
      var img = new Image();
      img.src = 'player.png';
      img.onload = function() {
        // Just for reference
        ctx.drawImage(img, 0, 0, 128, 128);
        ctx.drawImage(img, canvasW/2 - imgW/2, canvasH/2 - imgH/2, 128, 128);
        mark(ctx, "red");
        // Keep current context (transformations)
        ctx.save();
        // Put bottom center at origin
        ctx.translate(imgW/2, imgH);
        // Rotate
        // Beware the next translations/positions are done along the rotated axis
        ctx.rotate(45 * Math.PI / 180);
        // Mark new origin
        mark(ctx, "red");
        // Restore position
        ctx.translate(-imgW/2, -imgH);
        ctx.drawImage(img, 0, 0, imgW, imgH);
        mark(ctx, "green");
        // Draw it an wanted position
        ctx.drawImage(img, canvasW/2, canvasH/3, imgW, imgH);
        // Move elsewhere:
        ctx.translate(canvasW/2, canvasH/2);
        ctx.drawImage(img, 0, 0, imgW, imgH);
        mark(ctx, "blue");
        ctx.restore();
      }
    }
    function mark(ctx, color) {
     ctx.save();
//~      ctx.fillStyle = color;
//~      ctx.fillRect(-2, -2, 4, 4);
     ctx.strokeStyle = color;
     ctx.strokeRect(0, 0, imgW, imgH);
     ctx.restore();
    }
    </script>
  </head>
  <body onload='startup();'>
    <canvas id="canvas" style="position: absolute; left: 300px; top: 300px;" width="800" height="800"></canvas>
  </body>
</html>

My stumbling issue was that positioning the rotated figure is hard, because it is along the rotated axis: either we have to do some trigo math to paint at the primitive origin, or we have to draw on a secondary hidden canvas and then paint it on the target one.
Unless somebody else has a better idea?

Share:
34,605
Sukhpreet Singh Alang
Author by

Sukhpreet Singh Alang

Updated on April 05, 2020

Comments

  • Sukhpreet Singh Alang
    Sukhpreet Singh Alang about 4 years

    How do you rotate an image with the canvas html5 element from the bottom center angle?

    <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.translate(185, 185);
                        ctx.rotate(90 * 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>
    

    Unfortunately this seems to rotate it from the top left angle of the image. Any idea?

    Edit: in the end the object (space ship) has to rotate like a clock pointer, as if it is turning right/left.