2

I'm want to animate a rotation of my image. Now my image is rotating, but around one point. I want to make animation without moving my image(around the center of the image). I hope you know what I mean. Here is the part of my code:

ctx.save();
        ctx.translate(player.x+step, player.y+step);
        ctx.rotate(Math.radians(this.step%360));
        ctx.translate(-(player.x+step), -(player.y+step));

        ctx.drawImage(
            skeletonImage, 60, 65,
            this.width, this.height,
            this.x, this.y,
            this.width, this.height);

        ctx.restore();

Where step is increased in each frame.

AndroideuszPL
  • 385
  • 1
  • 2
  • 13

1 Answers1

1

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.

ggorlen
  • 44,755
  • 7
  • 76
  • 106