CANVAS에 그린 도형과 이미지가 흐릿하게 보일 때

맥북 레티나 디스플레이, 또는 모바일에서 확인 할 경우 canvas에 그린 도형과 이미지가 아래와 같이 흐릿하게 보이는 경우가 있다.

레티나 디스플레이나 모바일로 보는 경우 위의 ‘Ratio비적용‘과 ‘Ratio적용‘ 버튼을 눌렀을 때 원의 테두리가 흐릿하거나 또렷해지는 것을 확인 할 수가 있다. 고해상도 디스플레이에서 캔버스를 사용할 때 몇 가지 설정해주어야 하는 부분이 있는데 이 부분에 대해서 정리가 되어 있는 페이지가 있어서 가지고 와보았다.

http://www.html5rocks.com/en/tutorials/canvas/hidpi/?redirect_from_locale=ko

전체코드

var wWidth, wHeight
var canvas, ctx;
var devicePixelRatio, backingStoreRatio, ratio;

canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
wWidth = $(window).width();
wHeight = $(window).height();

devicePixelRatio = window.devicePixelRatio || 1,
backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
 ctx.mozBackingStorePixelRatio ||
 ctx.msBackingStorePixelRatio ||
 ctx.oBackingStorePixelRatio ||
 ctx.backingStorePixelRatio || 1,
ratio = devicePixelRatio / backingStoreRatio;

// style의 width, height 지정
canvas.style.width = wWidth + 'px';
canvas.style.height = wHeight + 'px';

// attribute에 ratio 값을 곱한 width, height 지정
canvas.width = wWidth * ratio;
canvas.height = wHeight * ratio;

// context scale 지정
ctx.scale(ratio, ratio);

// 원 그리는 부분
ctx.fillStyle = "#666";
var _radius = Math.floor( (Math.min(wWidth, wHeight) ) * 0.4 );
ctx.arc(wWidth/2, wHeight/2, _radius, 0, 2*Math.PI);
ctx.fill();

console.log(devicePixelRatio, backingStoreRatio, ratio);
1. 일단 변수 3개를 만들어서 최종적으로는 ratio 값을 도출한다.
devicePixelRatio, backingStoreRatio, ratio

devicePixelRatio = window.devicePixelRatio || 1,
backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1,
ratio = devicePixelRatio / backingStoreRatio;
2. canvas의 style에 width, height를 지정하고
canvas.style.width = wWidth + 'px';
canvas.style.height = wHeight + 'px';
3. canvas의 attribute에 ratio 값을 곱한 width, height를 지정한다.
canvas.width = wWidth * ratio;
canvas.height = wHeight * ratio;
4. 마지막으로 canvas context에 ratio만큼의 scale을 지정한다.
ctx.scale(ratio, ratio);