PixelRatio
PixelRatio
는 디바이스의 픽셀 밀도와 폰트 스케일에 접근할 수 있게 해준다.
적절한 크기의 이미지 가져오기
고해상도 디바이스에서는 더 높은 해상도의 이미지를 가져와야 한다. 일반적으로 표시할 이미지의 크기에 픽셀 비율을 곱하는 것이 좋은 방법이다.
const image = getImage({
width: PixelRatio.getPixelSizeForLayoutSize(200),
height: PixelRatio.getPixelSizeForLayoutSize(100),
});
<Image source={image} style={{width: 200, height: 100}} />;
픽셀 그리드 스냅핑
iOS에서는 엘리먼트의 위치와 크기를 29.674825와 같이 임의의 정밀도로 지정할 수 있다. 하지만 실제 물리적 디스플레이는 iPhone SE(1세대)의 640×1136이나 iPhone 11의 828×1792와 같이 고정된 픽셀 수를 가진다. iOS는 원본 픽셀을 여러 개로 확장해 눈속임을 통해 사용자가 지정한 값에 최대한 가깝게 표현하려고 한다. 이 기법의 단점은 결과적으로 엘리먼트가 흐릿하게 보일 수 있다는 것이다.
실제로 개발자들은 이 기능을 원하지 않으며, 흐릿한 엘리먼트를 방지하기 위해 수동으로 반올림 작업을 해야 한다. React Native에서는 모든 픽셀을 자동으로 반올림한다.
이 반올림 작업을 언제 수행할지 주의해야 한다. 반올림된 값과 반올림되지 않은 값을 동시에 사용하면 반올림 오차가 누적된다. 단 하나의 반올림 오차도 치명적일 수 있다. 예를 들어, 1픽셀 테두리가 사라지거나 두 배로 커질 수 있다.
React Native에서는 자바스크립트와 레이아웃 엔진 내부에서 임의의 정밀도로 숫자를 처리한다. 메인 스레드에서 네이티브 엘리먼트의 위치와 크기를 설정할 때만 반올림을 수행한다. 또한, 반올림은 부모가 아닌 루트를 기준으로 수행해 반올림 오차가 누적되지 않도록 한다.
예제
참조
메서드
get()
static get(): number;
기기의 픽셀 밀도를 반환한다. 몇 가지 예시는 다음과 같다:
PixelRatio.get() === 1
PixelRatio.get() === 1.5
PixelRatio.get() === 2
- iPhone SE, 6S, 7, 8
- iPhone XR
- iPhone 11
- xhdpi 안드로이드 기기
PixelRatio.get() === 3
- iPhone 6S Plus, 7 Plus, 8 Plus
- iPhone X, XS, XS Max
- iPhone 11 Pro, 11 Pro Max
- Pixel, Pixel 2
- xxhdpi 안드로이드 기기
PixelRatio.get() === 3.5
- Nexus 6
- Pixel XL, Pixel 2 XL
- xxxhdpi 안드로이드 기기
getFontScale()
static getFontScale(): number;
폰트 크기의 스케일링 비율을 반환한다. 이 값은 절대적인 폰트 크기를 계산하는 데 사용되는 비율이다. 따라서 폰트 크기에 크게 의존하는 엘리먼트는 이 값을 활용해 계산을 해야 한다.
- 안드로이드에서는 설정 > 디스플레이 > 글꼴 크기에서 사용자가 설정한 값을 반영한다.
- iOS에서는 설정 > 디스플레이 및 밝기 > 텍스트 크기에서 사용자가 설정한 값을 반영한다. 또한 설정 > 접근성 > 디스플레이 및 텍스트 크기 > 큰 텍스트에서도 값을 업데이트할 수 있다.
폰트 스케일이 설정되지 않은 경우, 이 메서드는 디바이스의 픽셀 비율을 반환한다.
getPixelSizeForLayoutSize()
static getPixelSizeForLayoutSize(layoutSize: number): number;
레이아웃 크기(dp)를 픽셀 크기(px)로 변환한다.
반환 값은 항상 정수로 보장된다.
roundToNearestPixel()
static roundToNearestPixel(layoutSize: number): number;
레이아웃 크기(dp)를 픽셀 단위로 정수 값에 가장 가까운 크기로 반올림한다. 예를 들어, PixelRatio가 3인 기기에서 PixelRatio.roundToNearestPixel(8.4)
는 8.33을 반환하며, 이 값은 정확히 (8.33 * 3) = 25픽셀에 해당한다.