简介
HiDPI 屏幕非常棒,可让所有内容看起来更流畅、更清晰。但这也给开发者带来了一系列新的挑战。在本文中,我们将探讨在高 DPI 屏幕环境中在画布中绘制图片时遇到的独特挑战。
devicePixelRatio 属性
我们从头再来一次。在我们还没有高 DPI 屏幕之前,一个像素就是一个像素(如果我们暂时忽略缩放和放大),就这样,您实际上不需要更改任何内容。如果您将某个元素的宽度设置为 100px,就只需要这样做。然后,前几款 HiDPI 移动手机开始弹出,窗口对象上具有略微神秘的 devicePixelRatio 属性,可用于媒体查询。通过此属性,我们可以了解像素值(我们称之为逻辑像素值)的比率,例如 CSS 如何转换为设备在渲染时实际使用的像素数。对于 devicePixelRatio 为 2 的 iPhone 4S,您会发现 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();