了解HTML Retina Canvas支持

时间:2016-03-05 22:33:40

标签: javascript html canvas

最近我进入了HTML canvas绘图和视网膜支持。如果没有在canvas - 元素上绘制的其他配置线,在视网膜显示上看起来有点模糊。

我知道视网膜显示器的像素是原来的四倍,因此默认情况下必须填充一些设备像素(否则图片的大小只有一半)。

示例
使用canvaswidth: 50px绘制HTML height: 50px

<canvas height="50px" width="50px">

普通屏幕上的浏览器只是绘制它(50 * 50像素)。视网膜显示器上的浏览器接收50x50px画布,但由于它是视网膜50 * 50,因此设备像素将小于预期。因此,浏览器在视网膜上绘制100 * 100像素。

画布上的清晰线条(单像素线黑/白)现在变得有点模糊,因为浏览器必须填充附近的像素并使用附近的周围 - 一些像素变成灰色。

如何修复:
这段代码应该解决问题:

// Returns: 1 on 'normal' screens, 2 on retina displays
var PIXEL_RATIO = (function () {
    var ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

    return dpr / bsr;
})();


function makeCanvasHiPPI(canvas) {
  canvas.style.width  = canvas.width  + "px";
  canvas.style.height = canvas.height + "px";

  canvas.width  *= PIXEL_RATIO;
  canvas.height *= PIXEL_RATIO;

  var context = canvas.getContext('2d');
  context.scale(PIXEL_RATIO, PIXEL_RATIO)
}

我认为代码的作用是什么:
使用画布上使用的这段代码,浏览器会被告知使用50 * 50px(这是canvas.style设置的内容),如上例所示 - 普通屏幕上50 * 50px,视网膜上100 * 100px 。 但是它在内部将画布处理为两倍大小的画布(至少在视网膜设备上),因此能够绘制通常由浏览器填充的像素。

棘手的部分(我不完全明白):
缩放。 Double&#39; canvas.width&#39;?很好,现在我们可以写更多的像素 - 更多信息。好。
但现在它已缩放,因此我们不会真正写入额外的像素(画布上只会显示0 - 50) - 这次填充设备像素的人是谁?我尝试了它没有缩放,它允许我在0-100的范围内在视网膜上绘制更细的线条(~1个设备像素) - 这些像素仍然有点模糊,但是缩放的线条更粗,但是晶莹剔透。模糊仅在大量缩放时可见。

专业规模:

  • 水晶线
  • 在我的例子中,没有任何比例不会产生强烈的黑色(在强烈变焦下可见)

Pro无规模:

  • 绘制行的能力
  • canvas.width实际上代表了我可以写入的像素。例如:
context.moveTo(0, context.canvas.height/2);
context.lineTo(context.canvas.width, context.canvas.height/2);

的工作原理。这不适用于缩放,因为context.canvas.width会返回未缩放的值。

我的问题:

  • 为什么线条会随着缩放而清晰,即使我自己甚至没有填充额外的像素?
  • 我如何处理误导性的回报值?
  • 我应该始终使用context.canvas.width / PIXEL_RATIO(带缩放)吗?这确实解决了问题,但在代码中看起来并不好(OCD踢出来)。我会继续这样做,直到我得到更好的东西。

2 个答案:

答案 0 :(得分:0)

  1. 在没有缩放的情况下,该行可能看起来很清晰,因为在您的情况下,canvas具有高dpi后备存储:http://www.html5rocks.com/en/tutorials/canvas/hidpi/

  2. 我不理解有关误导回报值的问题。一切似乎完全一致。您是否尝试在&#34;未缩放的&#34;中设置线宽为0.5?情况?

  3. 这取决于您的使用案例。如果&#34;未缩放&#34;很好,去吧。否则,如果您需要控制应用程序的DPI,请选择高DPI方法。

答案 1 :(得分:-2)

只需从HTML中删除:

<meta name='viewport' content='width=device-width' />

根本没有那条线。然后您的网页/游戏将使用设备的全屏分辨率。像素将始终是像素。 canvas.style.width将等于canvas.width,无需缩放。在iPhone X上,您的网站将为980px宽。因此,如果您使用宽度,请确定是否要显示移动网站,然后该检查将无法正常进行。这是用于画布页面和游戏的。