Использование тригонометрии для анимации HTML5 холста, но как расположить этот квадрат? - PullRequest
0 голосов
/ 03 мая 2020

Иногда вы можете sh вы могли бы go вовремя сказать себе, что математика действительно важна! Но я сомневаюсь, что слушал бы тогда. В последнее время я играл с тригонометрией в целях анимации, используя холст HTML5 в этом конкретном примере.

Это очень простая анимация: она помещает ar c по кругу вокруг центра холст. Положения X и Y рассчитываются на основе основных c тригонометрических функций синуса и косинуса. "SohCahToa". Я думаю, что начинаю понимать. Но почему-то я не могу понять, как нарисовать квадрат в середине одной из трех angular сторон.

GIF showing the problem.

let radius = 200;
let angle = 0;
x = centerX + Math.cos(angle) * radius;

ctx.beginPath();
ctx.fillRect(x/2, centerY, 20, 20);

https://codepen.io/melvinidema/pen/wvKPepa?editors=1010

Таким образом, ar c рисуется путем сложения центра холста с формулами переделки: (со) sinus - для X = Cos, для Y = Sin) из угол умножается на радиус круга.

Если мы возьмем только позицию X (красная линия) и хотим нарисовать квадратную половину позиции ar c. (То есть в середине красной линии ) мы должны просто разделить только что рассчитанную позицию X на два, верно? Но если я сделаю это, квадрат магическим образом будет нарисован за пределами круга.

Что происходит? Почему это ведет себя так? И какой расчет я должен использовать вместо этого, чтобы квадрат располагался в середине красной линии на протяжении всей анимации?

Заранее спасибо!

1 Ответ

1 голос
/ 03 мая 2020

Ваш x определен как:

x = centerX + Math.cos(angle) * radius;

, но когда вы хотите разделить на 2, вам просто нужно разделить Math.cos(angle) * radius, тогда как centerX - это нулевая точка, а ее стоять как есть.

Таким образом, прямоугольник должен быть размещен по адресу:

centerX + Math.cos(angle)/2

Кроме того, я думаю, будет лучше, если вы уменьшите половину ширины прямоугольника и получите:

centerX + Math.cos(angle)/2 - 10

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
let radius = 200;

function frame(angle) {
  const cx = canvas.width / 2,
  cy = canvas.height / 2,
  x = Math.cos(angle) * radius,
  y = Math.sin(angle) * radius;
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.moveTo(cx, cy);
  ctx.lineTo(cx+x, cy+y);
  ctx.lineTo(cx+x, cy);
  ctx.lineTo(cx, cy);
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(cx+x, cy+y, 10, 0, Math.PI*2);
  ctx.fill();
  ctx.fillRect(cx + x/2 - 10, cy - 10, 20, 20);
  ctx.closePath();
  requestAnimationFrame(()=>frame(angle+.03));
}
frame(0)
canvas {
display: block;
max-height: 100vh;
margin: auto;
}
<canvas width="500" height="500"></canvas>
...