مقدمه
صفحهنمایشهای HiDPI عالی هستند، همهچیز را روانتر و تمیزتر نشان میدهند. اما این دستگاهها چالشهای جدیدی را نیز برای توسعهدهندگان ایجاد میکنند. در این مقاله، چالشهای منحصربهفرد ترسیم تصاویر در بوم را در زمینه صفحهنمایشهای HiDPI بررسی میکنیم.
ویژگی devicePixelRatio
بیایید از ابتدا شروع کنیم. قبلاز اینکه صفحهنمایشهای HiDPI داشته باشیم، پیکسل همان پیکسل بود (اگر بزرگنمایی و مقیاسبندی را برای مدتی نادیده بگیریم) و همین بود، واقعاً نیازی به تغییر چیزی نداشتید. اگر چیزی را با عرض ۱۰۰ پیکسل تنظیم میکردید، همین بود و بس. سپس چند گوشی همراه HiDPI با ویژگی کمی مبهم devicePixelRatio در شیء پنجره ظاهر شدند و برای استفاده در پرسمانهای رسانه دردسترس قرار گرفتند. این ویژگی به ما امکان میدهد تا نسبت تبدیل مقادیر پیکسل (که به آن مقدار پیکسل منطقی میگوییم) در CSS را به تعداد واقعی پیکسلهایی که دستگاه هنگام پردازش استفاده میکند، درک کنیم. درمورد iPhone 4S که devicePixelRatio آن ۲ است، خواهید دید که مقدار منطقی ۱۰۰ پیکسل با مقدار دستگاه ۲۰۰ پیکسل برابر است.
جالب است، اما این برای ما توسعهدهندگان چه معنایی دارد؟ در روزهای اول، همه متوجه شدیم که این دستگاهها کیفیت تصاویر ما را ارتقا میدهند. ما تصاویر را با پهنای پیکسل منطقی عناصر خود ایجاد میکردیم و وقتی ترسیم میشدند، با 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();