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?
- Translate the context to the point on the canvas that the object should rotate about.
- Rotate the context.
- 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