了解HTML Retina画布支持

Las*_*ive 5 html javascript canvas

最近,我开始研究HTML canvas绘图以及它的视网膜支持。如果没有在- canvas元素上绘制进一步的配置线,则在视网膜显示器上看起来会有些模糊。

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

示例:使用和
绘制HTML 。canvaswidth: 50pxheight: 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)
}
Run Code Online (Sandbox Code Playgroud)

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

棘手的部分(我不太了解):
缩放。双“ canvas.width”?很好,现在我们可以写入更多像素-更多信息。好。
但是现在它已经缩放了,因此我们并没有真正写出多余的像素(画布上只会显示0-50)-这次谁来填充设备像素?我没有缩放就尝试了它,它使我可以在0-100范围内的视网膜上绘制较细的线(〜1个设备像素),尽管这些像素仍然有些模糊,缩放的线较粗,但晶莹剔透。模糊仅在很多缩放下可见。

专业规模:

  • 水晶线
  • 在我的示例中,没有缩放不会以某种方式产生强烈的黑色(在强缩放下可见)

无标度:

  • 绘制能力线
  • canvas.width真正代表了我可以写入的像素。例如:
context.moveTo(0, context.canvas.height/2);
context.lineTo(context.canvas.width, context.canvas.height/2);
Run Code Online (Sandbox Code Playgroud)

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

我的问题:

  • 为什么即使我自己都不填充多余的像素,缩放比例也能使线条清晰?
  • 我将如何处理误导性的返回值?
  • 我应该一直使用context.canvas.width / PIXEL_RATIO(缩放)吗?这确实解决了问题,但是在代码中看起来不太好(OCD插入)。我会继续这样做,直到我变得更好为止。

Ste*_*ein 1

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

  2. 我不明白有关误导性返回值的问题。一切看起来完全一致。您是否尝试过在“未缩放”的情况下将线宽设置为 0.5?

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

  • 我也读了这篇文章,但它并没有解决我的问题。我在 Safari 上(自动缩放支持 `backingStorePixelRatio`)。`devicePixelRatio = 2`(视网膜显示屏),`backingStorePixelRatio = 1`。 (2认同)