了解 HTML 视网膜画布支持

Understanding HTML Retina Canvas Support

本文关键字:支持 布支持 HTML 视网膜 了解      更新时间:2023-09-26

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

我确实知道视网膜显示器的像素是其四倍,因此默认情况下必须填充一些设备像素(否则图片将只有预期尺寸的一半)。

示例
绘制一个带有width: 50pxheight: 50px的 HTML canvas

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

普通屏幕上的浏览器只是绘制它(50 * 50像素)。视网膜显示器上的浏览器接收 50x50 像素的画布,但由于它是视网膜,因此 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*50 像素,视网膜上为 100*100 像素。但它在内部将画布处理为两倍大小的画布(至少在视网膜设备上),因此能够绘制通常由浏览器填充的像素。

棘手的部分(我不太明白):
缩放。双"画布宽度"?很好,现在我们可以写入更多像素 - 更多信息。好。
但是现在它被缩放了,因此我们并没有真正写入额外的像素(画布上只会显示 0 - 50)——这次谁填充了设备像素?我在没有缩放的情况下尝试过,它允许我在 0 - 1 范围内的视网膜(~1 个设备像素)上绘制更细的线条 - 这些像素仍然有点模糊,缩放的线条更粗,但晶莹剔透。模糊仅在大量变焦时可见。

专业秤:

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

专业无刻度:

  • 能够画出细线
  • 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(缩放)吗?这确实解决了问题,但在代码中看起来并不好(强迫症启动)。 我会继续这样做,直到我得到更好的东西。
  1. 该行可能看起来很清楚,没有缩放,因为 canvas 在您的情况下具有高 dpi 后备存储:http://www.html5rocks.com/en/tutorials/canvas/hidpi/

  2. 我不明白关于误导性返回值的问题。一切似乎都完全一致。您是否尝试过在"未缩放"的情况下将线宽设置为 0.5?

  3. 这实际上取决于您的用例。如果"未缩放"足够好,那就去做吧。否则,如果需要控制应用程序的 DPI,请选择高 DPI 方法。