简介
HiDPI 屏幕非常棒,能让所有内容看起来更流畅、更清晰。但它们也给开发者带来了一系列新的挑战。在本文中,我们将探讨在 HiDPI 屏幕上在画布中绘制图片所面临的独特挑战。
devicePixelRatio 属性
我们从头开始。在 HiDPI 屏幕出现之前,一个像素就是一个像素(如果我们暂时忽略缩放和缩放),仅此而已,您实际上不需要更改任何内容。如果您将某个元素的宽度设置为 100 像素,那么它就只有 100 像素。随后,首批 HiDPI 手机开始出现,它们在 window 对象上具有略显神秘的 devicePixelRatio 属性,并且可在媒体查询中使用。通过此属性,我们可以了解 CSS 等中的像素值(我们称之为逻辑像素值)与设备在渲染时使用的实际像素数之间的比率。以 iPhone 4S 为例,其 devicePixelRatio 为 2,您会看到 100 像素的逻辑值相当于 200 像素的设备值。
这很有趣,但对我们开发者来说意味着什么?在早期,我们都开始注意到,这些设备会放大我们的图片。我们之前是按照元素的逻辑像素宽度创建图片,当这些图片被绘制出来时,它们会按 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();