캔버스 위에서 캐릭터를 회전시키고 네온 효과 입히기

정혜인·2024년 12월 1일
0

이번 포스팅에서는 HTML Canvas를 사용하여 지도 위에 실시간 위치와 방향을 표시하는 방법에 대해 공유하려고 합니다.

예를 들어, 지도 위에 사용자 또는 객체의 위치와 그 방향을 나타낼 수 있는 방법을 구현해봤습니다.

이 과정에서 중요한 점은 위치 표시뿐만 아니라 방향 표시까지 추가하는 것이었습니다.

🌈 1. 네온 효과로 위치 표시하기

먼저, 위치를 표시할 때 네온 효과를 주기 위해 원을 그렸습니다.

이 원은 줌 레벨에 따라 크기가 조정되도록 설정했으며, 원의 색상은 파란색으로 은은하게 나타나도록 했습니다.

이를 위해 createRadialGradient를 사용하여 원 안에서 색상이 점점 투명해지도록 만들어줬습니다.

const radius = zoom * 3; // 원의 반지름 (줌 레벨에 따라 크기 조정)
const gradient = ctx.createRadialGradient(point.x, point.y, 0, point.x, point.y, radius);
gradient.addColorStop(0, 'rgba(0, 0, 255, 0.5)'); // 원의 중앙
gradient.addColorStop(1, 'rgba(0, 0, 255, 0)'); // 원의 바깥쪽

ctx.beginPath();
ctx.arc(point.x, point.y, radius, 0, 2 * Math.PI);
ctx.fillStyle = gradient;
ctx.fill();

🌟 2. 방향 표시하기 (회전된 이미지)

이제 중요한 부분인 방향 표시를 추가했습니다. 방향은 세모 모양의 아이콘을 사용하기도 했지만, 더 직관적인 이미지를 사용하기 위해 이미지로 방향을 표시하는 방법을 선택했습니다.

이미지는 중심으로부터 offset만큼 떨어진 위치에 배치된 후, 사용자의 방향을 따라 회전합니다.

회전된 방향을 제대로 나타내기 위해, direction 값에 맞춰 이미지를 회전시켰습니다. 중심에서부터 일정 거리만큼 떨어진 위치에 이미지를 놓고, 그 이미지는 지도 위에서 실제 방향에 맞게 회전하도록 했습니다.

const triangleSize = zoom * 2; // 이미지 크기 (줌 레벨에 따라 크기 조정)
const offset = zoom * 2; // 이미지가 중심에서 벗어나도록 할 거리

ctx.save();
ctx.translate(point.x, point.y); // 중심 위치로 이동
ctx.rotate(direction); // 방향에 맞춰 회전

const xOffset = 0; // 12시 방향 (x축)
const yOffset = -offset; // 12시 방향으로 위쪽으로 이동

ctx.beginPath();
ctx.drawImage(
  footStepsRef.current!, // 이미지 (로컬 파일로 로딩)
  xOffset - triangleSize / 2, // 이미지 위치
  yOffset - triangleSize / 2,
  triangleSize, // 이미지 크기
  triangleSize,
);
ctx.restore();

🌀 3. 회전 보정

이미지가 정확히 12시 방향에서 0도로 시작할 수 있도록 회전 보정도 추가했습니다.

기본적으로, direction 값이 320도에서 시작하도록 설정하였고, 이 값을 보정하여 이미지를 정확히 0도 방향으로 회전하도록 했습니다.

이렇게 하면 이미지가 12시 방향에서 시작하며, 이후 회전할 때 자연스럽게 움직입니다.

const correctedDirection = (direction - 320 + 360) % 360;  // 방향 보정
const radian = (correctedDirection * Math.PI) / 180; // 라디안 값으로 변환
ctx.rotate(radian); // 보정된 방향으로 회전

📌 4. 최종 코드

위 내용을 종합한 최종 코드는 다음과 같습니다.

이 코드를 통해 지도 위에 실시간으로 위치와 회전하는 방향을 함께 표시할 수 있었습니다.

const drawNeonCircleAndDirection = (
  ctx: CanvasRenderingContext2D,
  point: { x: number; y: number } | null,
  zoom: number,
  direction: number,
) => {
  if (!point) return;

  // 원 그리기 (네온 효과)
  const radius = zoom * 3;
  const gradient = ctx.createRadialGradient(point.x, point.y, 0, point.x, point.y, radius);
  gradient.addColorStop(0, 'rgba(0, 0, 255, 0.5)');
  gradient.addColorStop(1, 'rgba(0, 0, 255, 0)');

  ctx.beginPath();
  ctx.arc(point.x, point.y, radius, 0, 2 * Math.PI);
  ctx.fillStyle = gradient;
  ctx.fill();

  // 방향 표시
  const triangleSize = zoom * 2;
  const offset = zoom * 2;

  ctx.save();
  ctx.translate(point.x, point.y);

  // 방향 보정 (320도를 기준으로 0도로 보정)
  const correctedDirection = (direction - 320 + 360) % 360;
  const radian = (correctedDirection * Math.PI) / 180;
  ctx.rotate(radian);

  const xOffset = 0;
  const yOffset = -offset;

  ctx.beginPath();
  ctx.drawImage(
    footStepsRef.current!,
    xOffset - triangleSize / 2,
    yOffset - triangleSize / 2,
    triangleSize,
    triangleSize,
  );

  ctx.restore();
};

🖌 5. 결론...?

이 방법을 통해 실시간으로 지도 위에 위치와 방향을 표시하는 기능을 구현할 수 있었습니다.

HTML Canvas와 이미지 회전, 네온 효과 등을 활용하여 더 직관적이고 시각적인 표시가 가능해졌습니다.

canvas에 대해 많은 작업을 해본 적이 없었는데, 이렇게 예쁘게 완성되는 것을 보니…… 너무 예쁘더라고요….

확실히 저는 프엔 개발자인가 봅니다………………

0개의 댓글