Home > database >  HTML Canvas transform & rotate
HTML Canvas transform & rotate

Time:11-25

I want to draw a square and rotate it by 45deg.

It works, but I don't know why the transform applied is not the the center of the the square ( it's off by ~72px ) ?

How would I programatically calculate the transform required for any given square size ?

var canvas = document.querySelector('canvas');
canvas.width = 300;
canvas.height = 400;
let rotate = false;
let clear = true; // if set to false then compare the two squares.
let ctx = canvas.getContext('2d')
    setInterval(() => {
      ctx.fillStyle = 'white';
      clear && ctx.fillRect(0,0,canvas.width,canvas.height);
      ctx.fillStyle = 'black';
      ctx.save();
      rotate = !rotate;

      if ( rotate ) {
          ctx.translate(150,128); // the center of the square is 150 / 200 ?? 
          ctx.rotate(45 * Math.PI / 180); // 45 deg
      } else {
          ctx.translate(100,150); // top left of square
      }
      
      ctx.fillRect(0,0,100,100);
      ctx.restore();
    },1000)
<canvas style="border: 1px solid red"></canvas>

CodePudding user response:

Here is an working example:

Just change let paint = {"width":75,"height":75}; for new dimensions and it will center self.

1.414 is used for calculating diagonal of the box

let paint = {"width":75,"height":75};
var canvas = document.querySelector('canvas');
canvas.width = 300;
canvas.height = 400;
let rotate = false;
let clear = true; // if set to false then compare the two squares.
let ctx = canvas.getContext('2d')
    setInterval(() => {
      ctx.fillStyle = 'white';
      clear && ctx.fillRect(0,0,canvas.width,canvas.height);
      ctx.fillStyle = 'black';
      ctx.save();
      rotate = !rotate;

      if ( rotate ) {
         
          ctx.translate((canvas.width/2),(canvas.height/2)-((paint.height*1.414)/2)); // the center of the square is 150 / 200 ?? 
          ctx.rotate(45 * Math.PI / 180); // 45 deg
      } else {
          ctx.translate((canvas.width/2)-(paint.width/2),(canvas.height/2)-(paint.height/2)); // top left of square
      }
      
      ctx.fillRect(0,0,paint.width,paint.height);
      ctx.restore();
    },1000)
<canvas style="border: 1px solid red"></canvas>

CodePudding user response:

How about we translate to the center of the canvas once...
then do the drawing of the square(s) with an offset like:
ctx.rect(-25, -25, 50, 50)
in that the starting point is a negative of half the size of the square you are trying to draw

See sample code below:

var canvas = document.querySelector('canvas')
canvas.width = canvas.height = 160
let ctx = canvas.getContext('2d')
ctx.translate(canvas.width/2, canvas.height/2)
ctx.lineWidth = 5

setInterval(() => {
  ctx.beginPath()
  ctx.clearRect(-canvas.width, -canvas.height, canvas.width*2, canvas.height*2)
  ctx.rotate(45 * Math.PI / 180)
  ctx.rect(-25, -25, 50, 50)
  ctx.rect(10, 10, 8, 8)
  ctx.stroke()
}, 500)
<canvas style="border: 1px solid red"></canvas>

  • Related