[Canvas] #03. Rect, Arc

undefcat·2020년 3월 19일
0

canvas

목록 보기
3/6
post-thumbnail

getContext

캔버스에 도형을 그려보자.

도형을 그리려면 어떻게 해야할까? 당연하겠지만, 캔버스 API를 통해 그려야 할 것이다. 그러기 위해선 캔버스의 컨텍스트 객체를 얻어와야 한다. 이 컨텍스트 객체를 통해 우리는 도형을 그릴 것이다.

index.html

우선 아래와 같은 html파일을 준비한다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>HTML</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="module" src="index.js"></script>
</body>
</html>

canvas 태그와 이 canvas를 조작할 스크립트 파일을 준비한다. type="module"은 브라우저에서 해당 스크립트 파일을 ES6 Module로 다루게 해준다. Modulesimport를 참고해보도록 하자.

index.js

canvas는 다른 일반적인 태그와 다를바 없다. 캔버스의 컨텍스트 객체를 얻기 위해서는 HTMLCanvasElement를 먼저 얻어와야 한다.

const canvas = document.querySelector('#canvas')

그 다음, getContext메서드를 통해 컨텍스트를 얻는다.

const ctx = canvas.getContext('2d')

getContext2d 말고도 여러가지 타입 문자열을 매개변수로 받을 수 있는데, 궁금하다면 getContext MDN 문서를 참고하도록 하고 우리는 2d만을 사용할 것이다.

그 다음, 우린 캔버스의 크기를 브라우저에 꽉 차게 만들 것이다. 캔버스의 경우, 실제로 캔버스 위에 그림을 표현할 수 있는 크기를 키우려면 캔버스 태그의 width 속성과 height 속성을 줘야 한다. CSSwidthheight를 설정하면, 기본 캔버스 크기값(350x150)을 단지 확대시킬 뿐이다. 즉, 드로잉할 수 있는 영역인 350x150을 CSSwidth, height값 만큼 확대시키는 형태가 된다.

따라서 width, height을 직접 설정해 줄 것이다.

canvas.width = window.innerWidth
canvas.height = window.innerHeight

여기까지 했다면 기본 준비가 끝난 것이다.

사각형 그리기

컴퓨터 좌표계의 원점은 왼쪽 상단이라는 사실을 기억하라.

캔버스에서는 사각형을 그릴 때, fillRect 메서드를 사용한다.

메서드의 인터페이스는 다음과 같다.

void ctx.fillRect(x, y, width, height)

x, y는 사각형을 그리는 기준점이 된다. 이는 캔버스의 (0, 0), 즉 왼쪽 상단을 기준으로 하는 좌표계에서의 x y를 뜻한다. 그리고 이 x y 기준점은 그려질 사각형의 왼쪽 상단 꼭지점이 된다. width, height는 그 꼭지점으로부터 너비와 높이의 값을 뜻한다.

기억하자. 항상 좌표계의 시작은 왼쪽 상단이라는 것.

(50, 50)에서 너비, 높이 100의 사각형을 그리고 싶다면

ctx.fillRect(50, 50, 100, 100)

이렇게 메서드를 호출하면 된다.

위 그림을 생각해보면 아주 쉽게 이해할 수 있다.

기본적으로 그려지는 사각형은 검정색이다. 이를 바꿔보자.

ctx.fillRect(50, 50, 100, 100)

ctx.fillStyle = `rgba(255, 0, 0, 1)`
ctx.fillRect(100, 100, 100, 100)

위와 같이 보여질 것이다. fillStyle 프로퍼티로 설정된 값으로 사각형을 그린다.

위에서 보다시피, 캔버스는 말 그대로 도화지이다. 그림을 그리는 메서드를 호출할 때마다, 기존 도화지에 계속 덧그리게 된다.

이번엔 원을 그려보자. 원은 arc 메서드를 이용해서 그린다. 이 때, 우선 beginPath 메서드를 호출해야 한다.

path에 대한 개념은 포토샵, 일러스트레이터 등을 다뤄봤다면 잘 이해할 수 있는 개념이다.

MDN에서는 아래와 같이 정의한다.

A path is a list of points, connected by segments of lines that can be of different shapes, curved or not, of different width and of different color. A path, or even a subpath, can be closed.

즉, 곡선이나 직선을 표현하는 점들의 집합이라고 생각하면 된다.

아무튼, arc 메서드의 인터페이스는 아래와 같다.

void ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise])

x y는 원의 중심 좌표다. radius는 원의 반지름이다. startAngle은 현재 좌표계에서 원이 시작되는 각도이고, endAngle은 원이 끝나는 각도이다. anticlockwise는 기본값이 false인데, true로 설정하면 시계반대방향으로 원을 그린다.

원을 그리는 것은, 컴퍼스로 원을 그리는 것을 생각하면 된다. 원의 중심 (x, y)에 컴퍼스를 고정시키고, radius 만큼 벌린 뒤 startAngle부터 endAngle까지 시계방향으로 그린다.

anticlockwise?

시계반대방향의 의미는 무엇일까? 왜 기본적으로 시계방향으로 원을 그리는 것일까? 이는 컴퓨터 좌표계 때문인데, 컴퓨터 좌표계는 y값이 아래쪽이라고 했다.

우리가 일반적인 좌표계에서 원을 그릴 때, 각도가 증가하는 방향이 어디였는지를 생각해보면 쉽게 이해가 된다. 보통 1사분면에서 2사분면 쪽으로 원을 그렸다. 즉, 시계반대방향으로 원을 그렸고 이렇게 그릴 때 각도가 커지는 것을 일반적으로 배웠다.

하지만 컴퓨터의 좌표계는 다르다. 컴퓨터의 좌표계에서 각도가 증가하는 방향은 시계방향이다. 따라서 기본적으로 anticlockwisefalse이다.

radian

컴퓨터에서의 각도 단위는 degree값이 아니다. radian값이다.

위의 애니메이션에서도 쉽게 알 수 있듯이, radian은 원에서 반지름의 길이와 호의 길이가 같을 때 그 각도를 뜻한다.

360° = 2π rad 이다. 따라서 1° = π/180 rad이다.

그리자

startAngle은 원의 중심으로부터 시작하는 각도다. 원을 그리고자 한다면, startAngle은 0, endAngle은 2π이면 될 것이다.

π값은 자바스크립트에서 Math.PI 상수로 표현할 수 있다.

 // 도형 그리기를 시작한다.
ctx.beginPath()

// (200, 200)이 중심인 반지름 50의 원의 path를 그린다.
ctx.arc(200, 200, 50, 0, 2*Math.PI)

// path를 닫는다. 즉, 현재까지 그려진 path가 연결된다.
// path의 시작점과 끝점의 path가 연결된다.
// 이 경우, 원을 그렸으므로 그냥 원이다.
ctx.closePath()

// 초록색으로 채우는 스타일을 정하고
ctx.fillStyle = `rgba(0, 255, 0, 1)`

// 현재 닫힌 path에 색을 칠한다.
ctx.fill()

현재까지의 코드를 종합해보면

const canvas = document.querySelector('#canvas')
const ctx = canvas.getContext('2d')

canvas.width = window.innerWidth
canvas.height = window.innerHeight

// 검정색 사각형
ctx.fillRect(50, 50, 100, 100)

// 빨간색 사각형
ctx.fillStyle = `rgba(255, 0, 0, 1)`
ctx.fillRect(100, 100, 100, 100)

// 초록색 원
ctx.beginPath()
ctx.arc(200, 200, 50, 0, 2*Math.PI)
ctx.closePath()
ctx.fillStyle = `rgba(0, 255, 0, 1)`
ctx.fill()

이는 위와 같은 그림일 것이다.

다음엔?

지금까지 사각형과 원을 그려보았다. 핵심은

  1. 컴퓨터의 좌표계
  2. path
  3. 각도는 radian

이 정도일 것이다. 이해가 잘 되지 않는다면, 직접 위치나 startAngle, endAngle, anticlockwise 값을 바꿔가면서 그려보면 될 것이다. 그러면 쉽게 이해할 수 있다.

다음 챕터에서는 선을 그려보고, 벡터에 대해 알아보도록 하겠다.

이미지 출처

profile
초보개발자니뮤ㅠ

0개의 댓글