מבוא
מסכי HiDPI מקסימים, כך הכול נראה חלק ונקי יותר. אבל הם גם מציגים מפתחים לאתגרים חדשים. במאמר הזה נבחן את האתגרים הייחודיים של ציור תמונות על קנבס בהקשר של מסכי HiDPI.
המאפיין PixelRatio של המכשיר
נתחיל מההתחלה. לפני שהיו לנו מסכים ברזולוציית HiDPI, פיקסל היה פיקסל (אם מתעלמים לרגע מהגדלת התצוגה והשינוי של קנה המידה), וזה היה הכול. לא היה צורך לשנות שום דבר. אם הגדרתם משהו ברוחב 100px, זהו. לאחר מכן החלו להופיע כמה מכשירי HiDPI ניידים עם המאפיין devicePixelRatio הקצת מסתורי באובייקט window, שזמין לשימוש בבקשות מדיה. המאפיין הזה אפשר לנו להבין את היחס בין ערכי הפיקסלים (שנקראים 'ערך הפיקסל הלוגי') ב-CSS, לבין מספר הפיקסלים האמיתי שהמכשיר ישתמש בהם בתהליך הרינדור. במקרה של מכשיר iPhone 4S, עם devicePixelRatio של 2, הערך הלוגי של 100px שווה לערך של 200px במכשיר.
זה מעניין, אבל מה המשמעות של זה עבורנו המפתחים? בשלבים המוקדמים, כולנו התחלנו לשים לב שהתמונות שלנו מוגדלות על ידי המכשירים האלה. יצרנו תמונות ברוחב הפיקסלים הלוגי של הרכיבים שלנו, וכשהן הוצגו, הן הוגדלו לפי 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();