소개
HiDPI 화면은 모든 것이 더 부드럽고 선명하게 보이게 해 줍니다. 하지만 개발자에게는 새로운 과제도 안겨줍니다. 이 도움말에서는 HiDPI 화면 컨텍스트에서 캔버스에 이미지를 그릴 때의 고유한 문제를 살펴봅니다.
devicePixelRatio 속성
처음부터 시작해 보겠습니다. HiDPI 화면이 등장하기 전에는 확대/축소를 잠시 무시하면 픽셀은 픽셀이었고 그 이상은 아무것도 변경할 필요가 없었습니다. 너비를 100px로 설정하면 그게 전부였습니다. 그런 다음 처음 몇 개의 HiDPI 휴대기기가 window 객체에 약간 수수께끼 같은 devicePixelRatio 속성을 갖고 등장했으며 이 속성은 미디어 쿼리에서 사용할 수 있습니다. 이 속성을 사용하면 CSS의 픽셀 값 (논리적 픽셀 값이라고 함)이 렌더링 시 기기에서 사용할 실제 픽셀 수로 어떻게 변환되는지 비율을 파악할 수 있습니다. devicePixelRatio가 2인 iPhone 4S의 경우 100px 논리적 값이 200px 기기 값과 같습니다.
흥미롭지만 개발자에게는 어떤 의미가 있나요? 초기에는 이러한 기기에서 이미지가 확대되고 있다는 점을 모두가 인지하기 시작했습니다. 요소의 논리적 픽셀 너비로 이미지를 만들고 있었는데, 이미지가 그려질 때 devicePixelRatio로 업스케일되어 흐리게 표시되었습니다.
이 문제에 대한 사실상의 해결 방법은 devicePixelRatio로 확대한 이미지를 만든 다음 CSS를 사용하여 동일한 양만큼 축소하는 것이었습니다. 캔버스도 마찬가지입니다.
function setupCanvas(canvas) {
// Get the device pixel ratio, falling back to 1.
var dpr = window.devicePixelRatio || 1;
// Get the size of the canvas in CSS pixels.
var rect = canvas.getBoundingClientRect();
// Give the canvas pixel dimensions of their CSS
// size * the device pixel ratio.
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
var ctx = canvas.getContext('2d');
// Scale all drawing operations by the dpr, so you
// don't have to worry about the difference.
ctx.scale(dpr, dpr);
return ctx;
}
// Now this line will be the same size on the page
// but will look sharper on high-DPI devices!
var ctx = setupCanvas(document.querySelector('.my-canvas'));
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.stroke();