[canvas] canvas 크기 설정과 비율 맞추기

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);

scale 전 / 후

 


4번을 이용하면 좀 더 높은 해상도를 화면에 표시해줄 수 있다..

그러나 dpr이 너무 높아서 4번과 같이 적용하면 리소스를 많이 잡아먹을 수 있다.
고해상도의 디바이스에서도 필요 이상의 고해상도 이미지를 불러오는 것을 방지해 성능 최적화에도 도움이 되니 dpr이 3이상이면 다 3으로 통일하는 것이 메모리 절약 차원에서도 좋다.

const dpr = Math.min(window.devicePixelRatio, 3)|| 1;


'Canvas' 카테고리의 다른 글

[canvas] rotate() 메서드  (0) 2024.03.13