# 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="/files/a7P0EWEjqj9sAZO3pXPy" 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); // 캔버스 전체 영역 지우기
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/interactive-web/canvas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
