이전 글 : [Canvas-불꽃놀이-03] Canvas 설정하기
물리적 크기와 CSS 크기 설정을 통한 캔버스 해상도 조절
참고 : Optimizing Canvas
1. 해상도
- 13인치의 화면이 있는데 같은 크기의 화면이라도 고해상도 화면은 저해상도 화면보다 픽셀수가 많다
- 예를 들어 1920*1080 해상도의 13인치 화면보다 3840*2160 해상도의 화면이 더 많은 픽셀 수를 가지고 있어 더 선명한 이미지를 보여준다.
- 반면에 저해상도 화면은 픽셀 수가 적어 동일한 물리적 크기에서 10개로 채울 것을 5개로 채워야 되니 고해상도 보다 픽셀당 크기가 커져 상대적으로 선명도가 낮아질 수밖에 없다.
- 그렇기에 캔버스의 물리적 크기와 css크기가 같게 통일해버리면 고해상도 화면은 가진 성능에 비해 덜 선명한 이미지를 볼 수 밖에 없다. 더 나은 사용자 경험을 위해 사용자 화면의 DPR (Device Pixel Ratio)의 정보를 가져와 해상도를 조절해 주는 것이 좋다.
2. 해상도에 따른 픽셀 구조
- CSS 픽셀은 논리적 크기여서 해상도와는 관계없이 동일한 크기로 보인다.
- 고해상도 화면은 픽셀 수가 많아 크기가 같은 이미지도 저해상도 보다 더 많은 픽셀로 표현할 수 있기 때문에 저해상도 보다 더 선명하게 보인다. 그래서 DPR에 따라 CSS의 물리적 크기를 재정의 하면 각각의 CSS 픽셀이 조정하기 전보다 더 많은 물리적 픽셀을 사용하게 된다.
- DPR이 2인 화면에서는 1 CSS 픽셀당 2*2 = 4개의 물리적 픽셀이 사용된다. DPR이 클수록 같은 화면 크기에서 더 많은 픽셀로 이미지를 세밀하게 표현할 수 있어 선명한 이미지가 보인다.
- 반면에 DPR이 1인 화면에서는 1CSS 픽셀 당 1*1 = 1개의 물리적 픽셀이 사용되므로 물리적 픽셀의 크기가 커 DPR이 높은 거보단 덜 세밀하게 표현될 수밖에 없다.
3. DPR로 캔버스의 해상도 조절하기
- 앞에 이유로 고해상도 화면에서 선명한 이미지를 렌더 하려면 CSS 픽셀 크기에 DPR을 곱하여 물리적 크기를 늘려줘야 한다.
- 그렇기에 사용자 화면의 DPR 값을 확인하고 현재 캔버스 CSS크기에 DPR을 곱해 물리적 픽셀 크기를 늘려준다
this.canvas.width = this.canvasCssWidth * this.dpr;
this.canvas.height = this.canvasCssHeight * this.dpr;
- 캔버스의 물리적 크기를 키우면 픽셀 수가 늘어나서 해상도는 높아지지만 실제 화면에 렌더 되는 스케일은 기본 CSS 크기 그대로라서 원래 크기의 1/DPR 비율로 작게 표시된다.
- 예를 들어 DPR이 2인 경우 CSS 크기를 500px로 유지하면서 물리적 크기만 1,000px로 늘리면 화면에 원래 크기의 1/2 사이즈로 작고 밀집된 이미지가 나타난다.
- 그래서 CSS 기준으로 된 렌더링 스케일을 DPR만큼 키운 물리적 크기에 맞춰 context.scale(dpr, dpr)로 늘려줘야 픽셀 크기와 렌더링 스케일의 크기가 동일해져 원래 비율에 고화질의 이미지를 렌더링 할 수 있게 된다. (참고 : canvas scale() mdn)
- (참고) cavas context는 캔버스 요소에 그림을 그리기 위해 필요한 메서드와 속성을 제공하는 객체이다. 이 context 객체를 통해 캔버스에 아래처럼 픽셀의 크기를 늘리거나 조작하거나 그림, 애니메이션 등을 렌더링 하게 해주는 역할을 한다. (참고 - canvas getContext() mdn)
this.ctx.scale(this.dpr, this.dpr);
4. 캔버스의 CSS크기는 논리적 크기로 맞춰주기
- DPR(예: 2)에 맞춰 캔버스의 물리적 크기를 늘렸다면 실제 화면에 표시될 캔버스의 CSS 크기는 CSS의 논리적 크기로 설정해야 원래의 의도된 이미지를 확인할 수 있다.
- 그래야 CSS에서 맞춘 논리적 화면 크기에 DPR로 늘린 물리적 캔버스의 픽셀수를 가지게 되니 고해상도의 이미지를 선명하게 표현할 수 있다.
- 만약 동일하게 설정한다면 캔버스의 CSS크기도 확대되어 고밀도 효과가 사라져 선명한 이미지를 얻는 효과는 얻을 수 없다.
this.canvas.style.width = `${this.canvasCssWidth}px`;
this.canvas.style.height = `${this.canvasCssHeight}px`;
Github 링크
'Canvas > 불꽃놀이 프로젝트' 카테고리의 다른 글
[Canvas-불꽃놀이-06] TextData 클래스 (2) | 2024.11.18 |
---|---|
[Canvas-불꽃놀이-05] index.js에서 중요 이벤트 정의 (1) | 2024.11.18 |
[Canvas-불꽃놀이-03] Canvas 설정하기 (4) | 2024.11.16 |
[Canvas-불꽃놀이-02] UI 구성 (3) | 2024.11.16 |
[Canvas-불꽃놀이-01] 프로젝트 초기화 (1) | 2024.11.15 |