You can translate the canvas to the location you wish to draw at, rotate the canvas on this point, then draw the image with the following call:
ctx.drawImage(
img,
img.width / -2, // x
img.height / -2, // y
img.width,
img.height
);
Moving the x
and y
away from the center by half the width and height respectively places the center of the image (width / 2
, height / 2
) at 0, 0 on the canvas (the rotation point).
Here's a minimal, complete example:
const degToRad = deg => deg * Math.PI / 180;
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = canvas.height = 180;
const ctx = canvas.getContext("2d");
const player = {
x: canvas.width / 2,
y: canvas.height / 2,
angle: 0,
img: new Image()
};
player.img.onload = function () {
(function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(player.x, player.x);
ctx.rotate(degToRad(player.angle++ % 360));
ctx.drawImage(
player.img,
player.img.width / -2,
player.img.height / -2,
player.img.width,
player.img.height
);
ctx.restore();
requestAnimationFrame(update);
})();
};
player.img.src = "http://placekitten.com/100/100";
While I'm not sure what the specifics are for your game, I'd keep step
out of the rendering calculation. Use it purely to update the position, then render only when all new positions for entities have been calculated. Keep step sizes, velocities, etc, out of the rendering stage.