canvas 그리는 방법, 그리드, 직사각형, 삼각형을 그려보자 🎵

안녕하세요! 두두코딩 입니다 ✋
오늘은 Canvas 도형 그리기에 대해 알아보겠습니다.

해당 포스팅은 MDN의 자료 보고 정리한 자료입니다.

🖇 소스코드에 마우스를 올리고 copy 버튼을 누를 경우 더 쉽게 복사할 수 있습니다!

궁금한 점, 보안점 남겨주시면 성실히 답변하겠습니다. 😁
+ 감상평 댓글로 남겨주시면 힘이됩니다. 🙇

캔버스를 이용한 도형그리기

이전 포스팅을 통해 우리는 기본적으로 캔버스에 그리는 방법을 알아보았다. 이제 어떻게 캔버스 위해 선, 도형등을 그릴 수 있는지 알아보자.

캔버스 위에 물체를 그릴 때는 path를 사용하여 그리는 것이 필수적임으로 path에 대해서도 해당 포스팅에서는 추가로 알아볼 것이다.

그리드

그리는 것을 시작하기 앞서 캔버스 그리드 혹은 좌표공간 (coordinate space)에 대해 알아보자. 이전 포스팅을 통해 HTML canvas의 기본 사이즈는 가로 세로 각각 150px 이라는 것을 확인했을 것이다. 아래의 그림을 보자.

grid

그림을 확인해보면, 캔버스와 그리드가 있는 것을 볼 수 있다. 기본적으로 그리드의 1단위는 1px이다. 그렇다면 HTML canvas의 기본 사이즈 즉, 그리는 150x150 이 생성된다고 알 수 있다. 그리드의 원점은 좌측 상단의 (0,0)을 지칭한다.

모든 요소들은 그리드의 원점을 기준으로 그려진다. 예를 들어 drawRect이라는 함수를 그리기 위해 첫번째 두번째 인자로 주어진 (x,y)는 기준점을 바꾸지 않는 한 원점을 기준으로 설정된다. (기준점을 바꾸는 moveTO()의 예외는 잠시 접어두고 생각하자..)

포스팅의 후반부에는 원점을 이동하는 방법, 그리드를 회전하고 비율을 축소 / 확대 하는방법에 대해서도 다룰 것이다. (너무 겁먹지 말고.. 지금은 기본에 충실해보자.😲)

직사각형 그리기

<canvas> 요소는 오직 하나의 원시적인 도형만을 제공한다. 바로 직사각형이다. 다른 모든 도형들은 무조건 하나 이상의 path여러 점으로 이어진 선으로 만들어 진다.

직사각형을 그리는데, 3가지 함수가 존재한다.

  1. fillRect(x, y, width, height)
    • x, y 위치에 width, height 크기로 색칠된 사각형을 그리도록 하는 함수
  2. storkeRect(x, y, width, height)
    • x, y 위치에 width, height 크기의 사각형의 윤곽선만 그리도록 하는 함수
  3. clearRect(x, y, width, height)
    • x, y 위치에 width, height 크기의 부분을 지우는 직사각형을 그린다. 지워진 부분은 투명하게 보인다.

위의 코드가 적용된 예시로 확인해보자.

See the Pen graphic by 13634816 (@13634816) on CodePen.

위 코드는 처음으로 100x100 사이즈의 검은색 사각형을 그린다. 이후 60x60 사이즈의 사각형 크기로 도형 중앙을 지우게 되고 마지막으로 윤곽선만 존재하는 사각형을 집어 넣어준다. 해당 코드를 하나씩 따라 쳐보면서, 그려지는 순서 및 그리는 방법을 익혀보자.😎

경로 그리기

path<canvas>에서 직사각형 이외의 원시적인 도형이다. 경로는 점들의 집합이며, 선의 한 부분이 되며, 해당 선은 연결되어 여러가지의 도형 및 곡선을 이룰 수 있다. 새로운 도형 및 곡선은 두께와 색을 표현할수도 있다.

경로로 도형을 만들 떄 3가지 단계가 필요하다.

  1. 경로 생성하기
  2. 그리기 명령어를 활용한 경로상에 그리기
  3. 경로가 만들어 질 경우, 경로를 렌더링 하기 위해 윤곽선을 그리거나, 도형 내부를 채우기.

경로 생성하기

beginPath() 함수를 활용하여 새로운 경로를 만든다. 해당 명령어는 경로를 구성하고, 만들기 위해 사용된다.

우리가 경로를 생성하기 전 초기화를 위해 moveTo()는 함수를 이용해 명시적으로 표현하는 것이 좋다. beginPath()도 결국 moveTo()로 여기지기 때문에, 명시적으로 사용자는 beginPath()이후 moveTo()를 적어 주는 것을 습관화 하자.

그리기 명령어를 활용한 경로상에 그리기

물체를 구성할 때, 필요한 여러 경로를 설정하는데, 사용하는 함수이다. 그리기에 필요한 함수들 moveTo(), lineTo(), arc(), … 등은 아래에서 자세하게 다루도록 한다.

경로 랜더링

closePath()메소드를 호출해, 렌더링을 한다. 해당 메소드는 현재 점 위치와 시작점 위치를 직선으로 이어 도형을 닫는다. (도형을 닫는 다는 말은 도형을 생성하는 것이다.) 만약 도형이 이미 닫혀있거나, 점이 하나만 존재할 경우 아무동작도 수행하지 않는다.

fill() 명령어를 호출하게 될 경우 아직 미완성의 도형은 자동으로 닫히면서 색을 채운다. 즉, closePath()를 자동으로 호출한다. 따라서 fill()는 해당 함수를 사용할 필요없다. 반면에, stroke() 윤곽선을 채우는 함수는 명시적으로 closePath()를 적어주어야한다.

아래의 예시를 보자.

See the Pen graphic by 13634816 (@13634816) on CodePen.

펜(pen) 이동하기

moveTo()는 어떤 것을 그리지는 않지만, canvas 함수 중 가장 유용한 함수이다. 우리가 그림을 그릴 때, 펜 혹은 연필을 들어 다른 위치로 옮기는 경험을 해본적 있을 것이다. 다른 위치를 선택해 그리기 위해서는 도구를 옮겨야하는데, 그 해당 동작이 바로 moveTo()이다.

moveTo(x, y)

beginPath() 메소드 호출 시, 특정 시작점 설정을 위해 moveTo() 함수를 사용하는 것이 좋다.

아래의 예시를 통해 보자.

See the Pen graphic by 13634816 (@13634816) on CodePen.

예시는 smile 모양의 그림을 그린 것이다. 주석을 보면, 어떤 순서로 어떻게 그리는지가 나와있다. 우선, 해당 내용을 알기 위해서는 arc()의 사용법을 알아야한다. 추후 설명 예정이니, 해당 함수는 원을 그리는 함수라고 생각하자 (정확히는 호를 그리는 함수..)

펜 이동하기 라는 부분에서는 moveTo()의 동작을 보는 것이 중요하다. 해당 예시를 따라 쳐보고, moveTo()함수를 그렸을 때 어떻게 출력이 되는지 알아보자. 만약 주석 처리하고 그리게 될 경우 연필을 한번도 옮기지 않고 그냥 쭈우욱 그린 그림 처럼 나올 것이다.

선 그리기

우리가 직선을 그리기 위해서는 lineTo()라는 함수를 활용해야한다.

lineTo(x, y)

시작점은 이전에 그려진 경로에 의해 결정된 곳이다. 구체적으로, 이전 경로의 끝 점이 다음 경로의 시작점이다.

시작점은 우리가 위해서 배운 moveTo()를 활용해도 변경이 가능하다. (도구를 움직이면 위치가 바뀌니..)

lineTo()를 활용한다고 해서 바로 canvas위에 그려지지 않는다. 우리가 연필을 들고 어떻게 그릴 것이다 구상하는 것과 동일하다. canvas 위에 그려지기 위해선 우리가 색칠해서 그릴 건지 윤곽선으로 그릴 건지 등의 과정 (rendering) 이후 선이 눈에 보일 것이다.

아래의 예시를 통해 자세히 알아보자.

See the Pen graphic by 13634816 (@13634816) on CodePen.

위의 코드를 보면, 새로운 경로를 지정하기 위해 beginPath() 를 활용한다. moveTo()라는 함수로 연필을 이동시킨 후, lineTo()로 어디로 그릴 것인지 정한다.

이후 우리는 fill / stroke 어떤 것으로 rendering 할지를 결정하고 그림을 그린다. fill() 은 선을 모두 귿고 내부를 채우는 함수이다. stroke()는 윤곽선을 그리는 함수이다.

위에서도 언급했겠지만, fill()같은 경우 경로 내의 색이 채워지면서 closePath()를 호출해 도형을 완성한다. 하지만, stroke() 같은 경우 closePath()가 명시적으로 존재한다. 만약 해당 함수를 제거하고 수행할 경우 어떤 결과를 나타낼까 고민해보자.

(아마.. 도형이 아닌 선 두개가 연결된 것으로 보일 것이다. fill과 달리 꼭 close 해줘야한다는 점을 잊지말자!!)

추가로 있는 arc() 호 만들기 부분은 한숨 돌리고 보도록 하자! 너무 오래 쉬지 말고 여기 클릭해서 다음 내용을 같이 공부해보자!! 😌