소개
HiDPI 화면은 모든 것이 더 부드럽고 선명하게 보이게 해줍니다. 하지만 개발자에게 새로운 도전과제를 제시하기도 합니다. 이 도움말에서는 HiDPI 화면의 컨텍스트에서 캔버스에 이미지를 그릴 때의 고유한 문제를 살펴봅니다.
devicePixelRatio 속성
처음부터 시작해 보겠습니다. HiDPI 화면이 등장하기 전에는 픽셀이 픽셀이었고 (확대/축소는 잠시 무시하겠습니다) 그뿐이었습니다. 아무것도 변경할 필요가 없었습니다. 너비를 100픽셀로 설정하면 충분했습니다. 그런 다음 처음 몇 개의 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();