user13456653
user13456653

Reputation: 98

Why do canvas graphics not show up when using save and restore?

I am trying to test out rotation control for a video game, but when i implement save(); and restore(); nothing shows up. I dont know if this matters but the canvas is 500px by 500px;

let ctx = document.getElementById('c').getContext('2d');

let x, y;
x = y = 0;
let degree = 0;

document.addEventListener('mousemove', (e) => {
  x = e.clientX;
  y = e.clientY;
});

setInterval(() => {
  degree = Math.atan2(x - 250, -(y - 250));
  console.log(degree);
  ctx.save();
  ctx.translate(250, 250);
  ctx.rotate(degree);
  ctx.fillRect(250, 250, 50, 20);
  ctx.restore();
},1000/60);

Upvotes: 1

Views: 112

Answers (2)

user13456653
user13456653

Reputation: 98

ok, after some experimentation i have figured it out. because the origin was translated, the center of the screen became 0, 0. therefore the coordinates of the rectangle had to be changed to 0,0 to see it.

Upvotes: 0

benbotto
benbotto

Reputation: 2440

The main issue is that you're translating the rectangle to (250, 250) and drawing it at (250, 250), so the rectangle is off the screen. Put another way, the save/restore is working fine, you just can't see the rectangle.

You're also not clearing the canvas when you render.

const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');

let x = 0, y = 0;
let degree = 0;

document.addEventListener('mousemove', (e) => {
  x = e.clientX;
  y = e.clientY;
});

function render() {
  const degree = Math.atan2(x - 250, -(y - 250));
  console.log(degree);
  ctx.clearRect(0, 0, canvas.width, canvas.height); // Added.
  ctx.save();
  ctx.translate(250, 250);
  ctx.rotate(degree);
  ctx.fillRect(0, 0, 50, 20); // Changed.
  ctx.restore();
}

setInterval(() => requestAnimationFrame(render), 1000); // Changed.
#c {
  border: 1px solid black;
}
<canvas id="c" width="500" height="500"></canvas>

As an aside, you should use requestAnimationFrame to render. The code above adds it, but ideally you want your rendering to be based on the time that's elapsed since the last render. That way you get the same speed across devices, regardless of the device's speed.

Upvotes: 2

Related Questions