Почему графика canvas не отображается при использовании сохранения и восстановления?

#javascript #html #html5-canvas

#javascript #HTML #html5-canvas

Вопрос:

Я пытаюсь протестировать управление вращением для видеоигры, но когда я реализую save(); и restore(); ничего не отображается. Я не знаю, имеет ли это значение, но размер холста составляет 500 пикселей на 500 пикселей;

 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);
  

Ответ №1:

Основная проблема заключается в том, что вы переводите прямоугольник в (250, 250) и рисуете его в (250, 250), поэтому прямоугольник не отображается на экране. Другими словами, сохранение / восстановление работает нормально, вы просто не видите прямоугольник.

Вы также не очищаете холст при рендеринге.

 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>  

Кроме того, вы должны использовать requestAnimationFrame для рендеринга. Приведенный выше код добавляет это, но в идеале вы хотите, чтобы ваш рендеринг основывался на времени, прошедшем с момента последнего рендеринга. Таким образом, вы получаете одинаковую скорость на разных устройствах, независимо от скорости устройства.

Комментарии:

1. Я понял, что было не так, когда вы опубликовали свой ответ. Спасибо за совет по поводу requestAnimationFrame. 🙂

Ответ №2:

хорошо, после некоторых экспериментов я понял это. поскольку начало координат было переведено, центр экрана стал 0, 0. поэтому координаты прямоугольника пришлось изменить на 0,0, чтобы его увидеть.

Комментарии:

1. Рад, что вы разобрались. Это не совсем верно в отношении источника. Источник по-прежнему (0, 0), но все, что отображается, будет переведено и повернуто внутри мира. Обычно в графических терминах вы говорите о разных «пространствах» (пространство экрана, мировое пространство и т.д.). Обычно используются матрицы преобразования, которые перемещаются из одного пространства в другое, чтобы, например, выяснить, с какими объектами в мировом пространстве сталкивается мышь (координаты мыши находятся в пространстве экрана), И инверсии этих матриц идут противоположным путем.