Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating and moving an image in a canvas element?

I would like to move and rotate an image of a ball in a element. The ball is 68x68 and the canvas is 300x200. The ball moves along the x and y axis, flipping its x and y velocity when it hits a wall - all of this works. I just can't figure how to do rotation on top of the movement.

My draw() function, which I call through window.setInterval every 30ms, looks something like this:

  var draw = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.save();
    ctx.rotate(ball_radians);
    ctx.drawImage(ball_img, x, y);
    ctx.restore();

    // calculate new x, y, and ball_radians
  }

This makes the ball fly around the screen, so clearly I'm doing something wrong. What am I missing?

like image 332
mshafrir Avatar asked Dec 16 '22 18:12

mshafrir


1 Answers

  1. Translate the context to the point on the canvas that the object should rotate about.
  2. Rotate the context.
  3. Either:
    • Translate the context by the negative offset within the object for the center of rotation, and then draw the object at 0,0, or
    • Draw the image using the negative offset within the object for the center of rotation.

e.g.

ctx.save();
ctx.translate( canvasLocX, canvasLocY );
ctx.rotate( ballRotationInRadians );
ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
ctx.restore();

Note that if you need absolute speed, instead of saving and restoring the canvas (handling many properties that you didn't change) you can just undo your work:

ctx.translate( canvasLocX, canvasLocY );
ctx.rotate( ballRotationInRadians );
ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
ctx.rotate( -ballRotationInRadians );
ctx.translate( -canvasLocX, -canvasLocY );

The previous bit of premature optimization has been blindly parroted from someone else; I have not personally benchmarked to verify that it is correct.

Edit: I've added a mocked up working example of this here: http://phrogz.net/tmp/canvas_beachball.html

like image 148
Phrogz Avatar answered Dec 19 '22 08:12

Phrogz