canvas 태그의 크기를 어떻게 맞추는 것이 좋을까?
** 공통적으로 확인하기위에 검은 바탕의 canvas에 (10, 10) 위치에 10*10 크기의 흰색 정사각형을 생성한다.
최초 생성
- html파일에 canvas 태그만 생성하고 조정은 js파일에서 진행함
- canvas 자체의 크기와 canvas css의 크기는 width 300, height 150이다
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, 20, 20);
자, 이제 화면 크기를 조정해보자
1. canvas 자체의 크기만 변경
- canvas 자체의 크기를 width 600, height 600으로 변경하였고 canvas 태그의 width, height도 canvas 자체의 크기와 동일하다.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const canvasWidth = 600;
const canvasHeight = 600;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, 20, 20);
2. canvas 태그의 스타일만 변경
- canvas 태그의 스타일의 width 600px, height 600px로 설정하면 캔버스 태그 자체의 크기는 바뀌나 canvas 자체의 크기는 바뀌지 않는다
- canvas 자체의 크기는 여전히 width 300, height 150을 그대로인데 태그 자체의 크기가 늘어났으니 억지로 늘어나게 되어 아래 사진과 같이 비율이 깨진다. 600*600 이라는 화면 크기에 맞춰 흰 사각형의 width는 2배 늘어나고 height는 4배가 늘어난다.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio;
const canvasWidth = 600;
const canvasHeight = 600;
canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, 20, 20);
3. canvas 자체의 크기와 canvas 태그의 스타일을 같이 변경
- 둘다 같이 변경하면 1번과 같은 결과이긴 하다.
- 정석대로하려면 이렇게 해줘야 겠지
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio;
const canvasWidth = 600;
const canvasHeight = 600;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, 20, 20);
4. 기기의 devicePixelRatio를 이용해 좀 더 선명하게 만들기
- window의 devicePixelRatio는 현재 디스플레이 장치의 물리적 해상도와 css 픽셀 해상도의 비율을 나타낸다.
- dpr이 높을 수록 디스플레이는 더 많은 픽셀을 사용하여 더 높은 해상도를 제공한다. 즉 단일 css 픽셀을 그리기 위해 화면의 픽셀을 얼마나 사용해야하는지 알려주기 때문에 수치가 높을 수록 더 많은 픽셀을 표시할 수 있어 해상도가 높아진다고 볼 수 있다.
- devicePixelRatio가 1이면 1px을 그리기 위해 1*1, 1개의 픽셀을 사용하고, 2이면 1px을 그리기 위해 2*2, 4개의 픽셀을 사용하여 그리기 때문에 더 선명한 것이다.
- 그래서 dpr을 이용하면 canvas를 좀 더 선명하게 그릴 수 있다. canvas태그의 크기는 600*600인데 canvas자체의 크기는 1200*1200이 된다. canvas자체의 크기는 canvas태그의 크기에 맞추므로 600*600 화면에 1200*1200 화면을 표시해야 하므로 더 작아진다. 그래서 canvas context의 scale을 dpr만큼 곱해주어야 원래 비율에 맞게 canvas가 확대되고 600*600 화면에 1200*1200개의 픽셀을 표시했으니 canvas를 더 선명하게 표현할 수 있다.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio; // 현재 내가 사용하고있는 디스플레이의 dpr은 2이다.
let canvasWidth = 600;
let canvasHeight = 600;
// canvas의 실제 크기 설정
canvas.width = canvasWidth * dpr;
canvas.height = canvasHeight * dpr;
// canvas의 scale 조정
ctx.scale(dpr, dpr); // canvas의 context도 dpr만큼 곱해줘야 원래의 비율대로 나온다.
canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, 20, 20);
4번을 이용하면 좀 더 높은 해상도를 화면에 표시해줄 수 있다..
그러나 dpr이 너무 높아서 4번과 같이 적용하면 리소스를 많이 잡아먹을 수 있다.
고해상도의 디바이스에서도 필요 이상의 고해상도 이미지를 불러오는 것을 방지해 성능 최적화에도 도움이 되니 dpr이 3이상이면 다 3으로 통일하는 것이 메모리 절약 차원에서도 좋다.
const dpr = Math.min(window.devicePixelRatio, 3)|| 1;
'Canvas' 카테고리의 다른 글
[canvas] rotate() 메서드 (0) | 2024.03.13 |
---|