# Canvas

## Canvas

> **Canvas API**는 JavaScript 와 HTML `<canvas>` 엘리먼트를 통해 그래픽을 그리기 위한 수단을 제공한다.
>
> 애니메이션, 데이터 시각화, 그래픽, 게임 등 다양한 시각적 인터렉션을 구현하는데 사용되는 강력한 도구

### Canvas Size

> canvas의 **size**(width, height)는 **`인라인 속성`**&#xC73C;로 지정한 값과 **`css 스타일`**&#xB85C; 지정한 값은 서로 다르게 동작한다.

#### 인라인 속성

* 인라인 속성은 컨버스의 해상도(포함된 픽셀 수)를 정의한다.
* 캔버스 고유의 물리적인 크기
* 지정해주지 않으면 기본값은 300 x 150

{% hint style="info" %}
**css 스타일**로 사이즈를 지정하는 것은 일반적으로 화면에 나타내는 사이즈 크기를 조절하는 것을 의미한다

즉, 캔버스 고유의 크기를 강제로 화면에 보여지는 사이즈로 조절(압축)시킨다.&#x20;
{% endhint %}

```typescript
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d'); // canvas 2D 렌더링 컨텍스트

const canvasWidth = 300;
const canvasHeight = 300;

canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';

canvas.width = canvasWidth * 2;
canvas.height = canvasHeight * 2;
```

### DPR (Device Pixel Ratio)

> 하나의 css 픽셀을 그릴 때 사용되는 장치에 픽셀 수를 의미한다. \
> **DPR**이 높을수록 선명한 화면을 나타낸다.

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2Fl11BMya7c866IC5BFpum%2FDPR_viz.svg?alt=media&#x26;token=837beb73-a039-4976-85d1-2d6d892ffe2d" alt=""><figcaption></figcaption></figure>

```javascript
const DPR = window.devicePixelRatio; 
// 고해상도 디스플레이 환경에서는 픽셀 밀도가 높기 때문에 기본적으로 설정한 캔버스 크기만으로는 흐릿해 보일 수 있다.
// 집적도를 높히기 위해 캔버스 자체의 크기를 DPR값 만큼 곱한다.
canvas.width = canvasWidth * DPR;
canvas.height = canvasHeight * DPR;

ctx.scale(DPR, DPR);// 캔버스 요소 내부의 그래픽들 역시 동일하게 보여지기 위해 DPR값 만큼 곱한다.
```

{% hint style="info" %}
**`dpr`**&#xAC12;이 3 이상이라면 캔버스 크기를 그만큼 늘리면서 성능 이슈가 생길 수 있고, dpr이 2인 기기의 선명함 정도만으로도 충분하기 때문에  최대 dpr 값을 2로 선언한다.
{% endhint %}

### 원 그리기

```tsx
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI / 180 * 360);
ctx.fill(); // ctx.stroke();
ctx.closePath();
```

#### beginPath()

path를 그리기 시작한다고 알리는 메서드, 새로운 path를 그리기 시작하며, 이전 path는 **초기화**시킨다.

#### closePath()

path의 시작 지점과 현재 위치를 직선으로 연결하여 path를 닫는다.

#### fill()

현재 설정된 path에 색을 채운다.

* **fillStyle** → 채울 색상을 설정 `ctx.fillStyle = 'red'`

#### stroke()

현재 설정된 path에 윤곽선을 그린다.

#### arc()

원을 그리는 메소드, 인자의 정보는 아래와 같다.

* **`x: number`**→ 시작하는 x 위치
* **`y: number`**→ 시작하는 y 위치
* **`radius: number`**→ 반지름의 길이
* **`startAngle: number`** → 시작하는 각도
* **`endAngle: number`** → 끝나는 각도
* **`counterclockwise: boolean | undefined`**→ 시계방향(false, default) or 반시계방향(true)

{% hint style="info" %}
각도는 `degree` 값이 아닌 `radian` 값을 사용하기 때문에 `Math.PI / 180 * [degree]`로 기입해야 한다. 즉, 각도 1도의 값은. PI(3.14)를 180으로 나눈값과 같다.

* 180 degree = π radian
* 1 degree = π / 180 radian
* x degree = x \* π / 180 radian
{% endhint %}

#### clearRect(x, y, width, height)

지정한 영역을 지우는 메서드

```typescript
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // 캔버스 전체 영역 지우기
```
