HTML 캔버스에서 회전 방법의 미스터리

this w3school's tutorial에 이어 HTML 캔버스로 아날로그 시계를 만들었습니다.

만드는 과정에서 캔버스의 신비를 접하고 많이 당혹스러웠어요!
그러나 Stack Overflow 덕분에(내 질문에 답변한 Kaiido 덕분에) HTML 캔버스의 작동 방식을 이해할 수 있었던 것 같습니다.

이제 이해를 공유합니다.

문제가 무엇입니까?



튜토리얼에는 5개의 단계가 있으며 "Clock Numbers"은 나에게 Chinese Wall이었습니다.
이 섹션에서는 각 숫자를 시계의 올바른 위치에 수직으로 배치합니다.

다음 기능 drawNumbers 은 이를 가능하게 합니다.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let radius = canvas.height/2;
ctx.translate(radius, radius);
radius = radius * 0.9;

function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
}

function drawNumbers(ctx, radius) {
  var ang;
  var num;
  ctx.font = radius * 0.15 + "px arial";
  ctx.textBaseline = "middle";
  ctx.textAlign = "center";
  for(num = 1; num < 13; num++){
    ang = num * Math.PI / 6;
    ctx.rotate(ang);
    ctx.translate(0, -radius * 0.85);
    ctx.rotate(-ang);
    ctx.fillText(num.toString(), 0, 0);
    ctx.rotate(ang);
    ctx.translate(0, radius * 0.85);
    ctx.rotate(-ang);
  }
}


함수의 for-loop에서 많은 rotate 메서드가 있음을 알 수 있습니다.
그들은 여러 번 회전하고 다시 회전하는 것처럼 보였고 그것은 나를 혼란스럽게 했습니다.

w3school의 튜토리얼에 대한 자세한 설명이 없어서 실마리가 없었습니다! (추가해주세요!)

이 for 루프에서 일어나는 일은...



먼저 1가 어떻게 배치되는지 살펴보고 코드의 각 줄에서 어떤 일이 발생하는지 살펴보겠습니다. (for-loop 내부에서만)
  • ang는 30도에 해당하는 π/6 라디안입니다.
  • ctx.rotate(ang) 전체 캔버스를 시계 방향으로 30도 회전합니다.ctx.translate(radius, radius);를 이용하여 회전 중심점을 원점에서 시계의 중심으로 바꾸었기 때문에(최종 코드here 참조) 아래 그림과 같이 회전합니다.

    노란색 사각형은 원래 위치를 나타내고 회색 사각형은 현재 위치를 나타냅니다.
    회색이 노란색 위에 있는 것으로 가정하고 30도 회전합니다.
    또한 녹색 원은 기준으로 설정된 회전 중심점입니다.
  • ctx.translate(0, -radius * 0.85); 전체 캔버스를 y 방향으로 이동합니다. 값이 음수이므로 올라갑니다.

    이제 캔버스가 30도 회전되었으므로 y 방향이 대각선 방향으로 보입니다.
  • ctx.rotate(-ang) 전체 캔버스를 시계 반대 방향으로 30도 회전합니다.
  • ctx.fillText(num.toString(), 0, 0);는 이번에는 1라는 숫자를 보여줍니다.

    숫자는 수직이고 올바른 위치에 위치합니다.
    그러나 잘못된 타이밍에 "fillText"를 입력하면 숫자가 다르게 표시됩니다. 아래 예를 살펴보십시오.
    전체 캔버스를 다시 회전하기 전에 "fillText"라고 가정합니다.

    for(num = 1; num < 13; num++){
    ang = num * Math.PI / 6;
    ctx.rotate(ang);
    ctx.translate(0, -radius * 0.85);
    ctx.fillText(num.toString(), 0, 0); //"fillText" before rotating back.
    ctx.rotate(-ang);
    ctx.rotate(ang);
    ctx.translate(0, radius * 0.85);
    ctx.rotate(-ang);
    }
    

    숫자가 기울어져 있습니다.
    주의하고 언제 어떤 방법을 사용해야 하는지 확인하십시오!
  • 다시 ctx.rotate(ang)는 전체 캔버스를 시계 방향으로 30도 회전합니다.
  • ctx.translate(0, radius * 0.85); 전체 캔버스를 y 방향으로 이동합니다. 이번에는 값이 양수이므로 내려갑니다.
  • ctx.rotate(-ang) 전체 캔버스를 시계 반대 방향으로 30도 회전합니다. 원래 위치로 돌아옵니다.

  • 그것이 하나의 번호에 대한 모든 프로세스입니다. 위치를 원래 위치로 되돌린 후 12번에 도달할 때까지 동일한 작업이 차례로 수행됩니다.



    캔버스가 어떻게 변형되는지 실제로 볼 수 없기 때문에 무슨 일이 일어나고 있는지, 특히 rotate 방법을 이해하기 어려웠습니다.

    이것은 나의 이해이고 과정을 시각화하려는 시도이므로 여기서 잘못된 점을 발견하면 의견을 남기고 지적하십시오.

    고맙습니다!

    좋은 웹페이지 즐겨찾기