Javascript 了解HTML画布支持

Javascript 了解HTML画布支持,javascript,html,canvas,Javascript,Html,Canvas,最近我进入了HTMLcanvasdrawing和视网膜对它的支持。在画布上没有进一步的配置线-元素在视网膜显示器上看起来有点模糊 我知道视网膜显示器有四倍的像素,因此在默认情况下必须填充一些设备像素(否则图片的大小只有预期的一半) 示例: 绘制一个宽度为50px、高度为50px的HTMLcanvas 普通屏幕上的浏览器只是绘制它(50*50像素)。视网膜显示器上的浏览器接收50x50px画布,但由于它是视网膜,因此50*50设备像素将小于预期值。因此,浏览器在视网膜上绘制100*100像素 画

最近我进入了HTML
canvas
drawing和视网膜对它的支持。在
画布上没有进一步的配置线
-元素在视网膜显示器上看起来有点模糊

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

示例
绘制一个宽度为50px、高度为50px的HTML
canvas

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

棘手的部分(我不太明白):
缩放。双“canvas.width”?好的,现在我们有了更多的像素,我们可以写入更多的信息。好
但是现在它是缩放的,因此我们不会真正写入额外的像素(画布上只显示0-50)-这次谁填充了设备像素?我在没有缩放的情况下尝试了它,它允许我在0-100范围内的视网膜上绘制更细的线(~1个设备像素)——这些像素仍然有点模糊,缩放的线更粗,但非常清晰。模糊仅在放大时可见

专业音阶:

  • 晶线
  • 在我的示例中,“无比例”不会产生强烈的黑色(在强烈缩放下可见)
专业无刻度:

  • 画细线的能力
  • canvas.width
    真正代表了我可以写入的像素。例如:
工作。这不适用于缩放,因为
context.canvas.width
返回未缩放的值

我的问题:

  • 为什么即使我自己都没有填充额外的像素,但缩放后的线条仍然清晰
  • 我将如何处理误导性的返回值
  • 我是否应该始终使用
    context.canvas.width/PIXEL\u RATIO
    (带缩放)?这确实解决了问题,但在代码中看起来不太好。我会一直坚持下去,直到找到更好的
  • 由于canvas在您的案例中具有高dpi备份存储,因此在不进行缩放的情况下,该行可能看起来很清晰:

  • 我不理解关于误导返回值的问题。一切似乎完全一致。在“未缩放”的情况下,是否尝试将线宽设置为0.5

  • 这实际上取决于您的用例。如果“无标度”足够好,那就去吧。否则,如果您需要控制应用程序的DPI,请使用高DPI方法


  • 只需从HTML中删除:

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

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

    带有“误导性”的意思是
    context.canvas.width
    返回例如100,当我只能绘制到像素50时。如果你问我的话,这是相当误导的。正如你在发布的代码中所看到的,它实际上已经使用了后台存储。单独打印
    dpr
    bsr
    可以解决混淆,更好地解释发生了什么。你可能想在问题中添加你正在使用的浏览器,因为Safari和Chrome处理后台存储的方式不同。我也读了这篇文章,但它没有明确我的问题。我在Safari上(自动缩放备份
    backingStorePixelRatio
    devicePixelRatio=2
    (视网膜显示),
    BackingsStorePixelRatio=1
    。缩放效果不会变得模糊的原因是,在绘制本机像素之前转换的是绘制数学,而不是先绘制然后转换生成的像素(这本质上就是非视网膜代码造成初始模糊的原因)。
    <meta name='viewport' content='width=device-width' />