PixelRatio في React Native
يسمح PixelRatio
بالوصول إلى كثافة البكسل (pixel density) ومقياس الخط الخاصّ بالجهاز.
جلب صورة مضبوطة الحجم
إذا كنّا نعمل على جهاز ذي كثافة بكسل عاليةٍ فإننا سنحصل على صورةٍ بدقّةٍ أعلى. ولقد وُجد تجريبيًّا أنّ ضرب حجم الصورة بمعدل البكسل (pixel ratio) هي أفضل قاعدةٍ لتحديد كثافة البكسل الضرورية لعرض صورةٍ ما.
var image = getImage({
width: PixelRatio.getPixelSizeForLayoutSize(200),
height: PixelRatio.getPixelSizeForLayoutSize(100)
});
<Image source={image} style={{ width: 200, height: 100 }} />;
التقاط شبكة البكسل
يمكن تحديد مواقع وأبعاد العناصر بدقّةٍ كيفيّة على منصّة iOS، مثلًا 29.674825، إلا أن الشاشة لها عددٌ محدّدٌ من البكسلات في النهاية، مثلًا 640x960 في جهاز iPhone 4 و 750×1334 في جهاز iPhone 6. تحاول iOS أن تلتزم بالقيمة التي يريدها المستخدم قدْرَ الإمكان، وذلك بنشر بكسل أساسيٍّ واحدٍ إلى عدّة بكسلات لخداع العين، غير أنّ سلبية هذه الطّريقة تتمثّل في أنّ العنصر يبدو بشكلٍ ضبابيٍّ.
في الواقع وُجد أنّ المطورين لا يرغبون بهذه الميّزة بل يقومون بتنفيذ عملية التقريب (rounding) هذه يدويًّا لتجنّب الحصول على عناصر ضبابيّة. تقرّب جميع البكسلات تلقائيًا على React Native.
عند تنفيذ عملية التقريب هذه يجب الانتباه لكي لا نعمل على القيم المقرَّبة وغير المقرًّبة في آنٍ واحدٍ، لأن ذلك سيؤدي إلى تراكم أخطاء التّقريب. إن حصول خطأ تقريبٍ وحيد يُعدٍّ فادحًا لأنه سيؤدّي إلى اختفاء بكسل واحدٍ من الحوافّ أو مضاعفته.
كل شيء مكتوب بلغة JavaScript وضمن محرك التخطيط (layout engine) على React Native يعمل بأرقام ضبطٍ كيفيّةٍ، وذلك عند تحديد موقع وأبعاد العنصر الأصليّ الذي نقربه في المهمّة الرّئيسيّة (main thread) فقط، كما أن التقريب يتمّ متناسبًا مع الجذر أكثر من الأب (parent)، لتجنّب تراكم أخطاء التّقريب.
مثال
import React from "react";
import { Image, PixelRatio, ScrollView, StyleSheet, Text, TextInput, View } from "react-native";
const size = 50;
const cat = {
uri: "https://reactnative.dev/docs/assets/p_cat1.png",
width: size,
height: size
};
const App = () => (
<ScrollView style={styles.scrollContainer}>
<View style={styles.container}>
<Text>Current Pixel Ratio is:</Text>
<Text style={styles.value}>{PixelRatio.get()}</Text>
</View>
<View style={styles.container}>
<Text>Current Font Scale is:</Text>
<Text style={styles.value}>{PixelRatio.getFontScale()}</Text>
</View>
<View style={styles.container}>
<Text>On this device images with a layout width of</Text>
<Text style={styles.value}>{size} px</Text>
<Image source={cat} />
</View>
<View style={styles.container}>
<Text>require images with a pixel width of</Text>
<Text style={styles.value}>
{PixelRatio.getPixelSizeForLayoutSize(size)} px
</Text>
<Image
source={cat}
style={{
width: PixelRatio.getPixelSizeForLayoutSize(size),
height: PixelRatio.getPixelSizeForLayoutSize(size)
}}
/>
</View>
</ScrollView>
);
const styles = StyleSheet.create({
scrollContainer: {
flext: 1,
marginTop: "2em",
justifyContent: "center",
},
container: {
justifyContent: "center",
alignItems: "center"
},
value: {
fontSize: 24,
marginBottom: 12,
marginTop: 4
}
});
export default App;
التوابع
get()
static get()
يعيد كثافة البكسل الخاصّة بالجهاز، من أمثلة ذلك:
PixelRatio.get() === 1
- لأجهزة mdpi Android
PixelRatio.get() === 1.5
- لأجهزة hdpi Android
PixelRatio.get() === 2
- لأجهزة iPhone SE, 6S, 7, 8
- لأجهزة iPhone XR
- لأجهزة iPhone 11
- لأجهزة xhdpi Android
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 Android
PixelRatio.get() === 3.5
- لأجهزة Nexus 6
- لأجهزة Pixel XL, Pixel 2 XL
- لأجهزة xxxhdpi Android
getFontScale()
static getFontScale(): number
يعيد معامل قياس حجوم الخط، وهو عبارة عن المعدَّل المستخدم لقياس حجم الخط المطلق، لذا يتوجب على العناصر التي تعتمد عليه بكثرة القيام بالحسابات باستخدام القيم التّالية:
- على منصة Android نحصل على هذه القيمة من مجموعة تفضيلات المستخدم على المسار Settings > Display > Font size
- على منصة iOS نحصل على هذه القيمة من مجموعة تفضيلات المستخدم على المسار Settings > Display & Brightness > Text Size، وأيضا يمكن أن تُحدَّث على المسار Settings > Accessibilty > Display & Test Size > Larger Text
ويعيد معدَّل البكسل للجهاز إذا لم يكن مقياس الخط محدّدًا.
getPixelSizeForLayoutSize()
static getPixelSizeForLayoutSize(layoutSize: number): number
يحوِّل حجم التخطيط (dp) إلى الحجم بالبكسل (px)، وذلك لضمان إعادة عددٍ صحيحٍ.
roundToNearestPixel()
static roundToNearestPixel(layoutSize: number): number
يقرّب حجم التّخطيط (dp) إلى أقرب حجم تخطيطٍ موافقٍ لعددٍ صحيحٍ من البكسلات، فمثلاً في الجهاز الذي يكون معدل البكسل (PixelRatio) فيه 3 يتم تقريب حجم التخطيط 8.4 dp كما يلي: PixelRatio.roundToNearestPixel(8.4) = 8.33
والذي يوافق تماما (8.33 * 3) = 25 بكسل.