परिचय
HiDPI स्क्रीन बहुत अच्छी होती हैं. इनकी मदद से, स्क्रीन पर मौजूद सभी चीज़ें बेहतर और साफ़ दिखती हैं. हालांकि, इनसे डेवलपर के सामने नई चुनौतियां भी आती हैं. इस लेख में, हम HiDPI स्क्रीन के संदर्भ में कैनवस में इमेज ड्रॉ करने से जुड़ी खास चुनौतियों पर नज़र डालेंगे.
devicePixelRatio प्रॉपर्टी
चलिए, एक शुरुआत से करते हैं. जब हमारे पास HiDPI स्क्रीन नहीं थीं, तब एक पिक्सल एक पिक्सल होता था. ज़ूम और स्केलिंग को कुछ समय के लिए अनदेखा करने पर, आपको कुछ भी बदलने की ज़रूरत नहीं थी. अगर आपने किसी एलिमेंट की चौड़ाई 100 पिक्सल पर सेट की है, तो उसे सिर्फ़ 100 पिक्सल चौड़ा ही दिखाया जाएगा. इसके बाद, पहले कुछ HiDPI मोबाइल हैंडसेट, विंडो ऑब्जेक्ट पर थोड़ी सी अनिगमैटिक devicePixelRatio प्रॉपर्टी के साथ पॉप-अप होने लगे. साथ ही, ये मीडिया क्वेरी में इस्तेमाल के लिए उपलब्ध थे. इस प्रॉपर्टी की मदद से हम यह समझ पाए कि पिक्सल वैल्यू (जिसे हम लॉजिकल पिक्सल वैल्यू कहते हैं) का अनुपात किस तरह होता है. जैसे, सीएसएस, रेंडर करने के लिए डिवाइस के इस्तेमाल किए जाने वाले पिक्सल की असल संख्या को बदल देगा. iPhone 4S के मामले में, जिसका devicePixelRatio 2 है, आपको दिखेगा कि 100px की लॉजिकल वैल्यू, 200px की डिवाइस वैल्यू के बराबर है.
यह दिलचस्प है, लेकिन डेवलपर के तौर पर इसका क्या मतलब है? शुरुआत में हम सभी ने यह महसूस किया कि इन डिवाइसों से हमारी इमेज को बेहतर बनाया जा रहा है. हम अपने एलिमेंट की लॉजिकल पिक्सल चौड़ाई पर इमेज बना रहे थे. इन्हें ड्रॉ करने पर, इन्हें devicePixelRatio के हिसाब से अपस्केल किया जाता था और ये धुंधली हो जाती थीं.
इस समस्या को हल करने के लिए, इमेज को devicePixelRatio के हिसाब से बड़ा किया जाता है. इसके बाद, सीएसएस का इस्तेमाल करके इमेज को उसी अनुपात में छोटा किया जाता है. कैनवस के लिए भी यही तरीका अपनाया जाता है!
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();