了解HTML视网膜画布支持 [英] Understanding HTML Retina Canvas Support

查看:92
本文介绍了了解HTML视网膜画布支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我进入了HTML canvas 绘图和视网膜对它的支持。没有进一步的配置,在画布 -element上绘制的线在视网膜显示上看起来有些模糊。



我明白视网膜显示器的像素是其四倍,因此必须默认填充一些设备像素(否则图像只有一半尺寸打算)。

示例

使用绘制HTML canvas code> width:50px height:50px



<$ 普通的 / em>屏幕只是绘制它(50 * 50像素)。视网膜显示器上的浏览器会接收到50x50px的画布,但由于它是视网膜50 * 50,所以设备像素会较小。因此,浏览器会在视网膜上绘制100 * 100像素。



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



如何解决它:

Th代码应该可以解决问题:

  //返回值:'普通'屏幕上显示1,视网膜显示屏上显示2 
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;
})();


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



棘手的部分(我不明白):

缩放。双canvas.width?很好,现在我们可以写更多的像素 - 更多信息。好。

但是现在它被缩放了,因此我们不会真的写入额外的像素(只有0 - 50会显示在画布上) - 谁填充设备像素时间?我在没有缩放的情况下尝试了它,它允许我在0-100范围内的视网膜(〜1设备像素)上画出更细的线条 - 尽管这些像素仍然有点模糊,但缩放线条更粗,但清澈透明。模糊只有很多变焦才可见。



缩放比例:




  • 水晶线

  • 没有缩放比例在我的例子中没有产生强烈的黑色(在强放大下可见)



没有比例:
$ b


  • 绘制细线

  • canvas.width 确实代表我可以写入的像素。例如:


  context.moveTo(0,context.canvas.height / 2); 
context.lineTo(context.canvas.width,context.canvas.height / 2);

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



我的问题:
$ b

  • 为什么这条线的缩放比较清晰,即使我甚至没有填充我自己的额外像素

  • 我会如何处理误导性的退货价值?

  • 我应该总是使用 context.canvas.width / PIXEL_RATIO (带缩放)吗?这确实解决了问题,但在代码中看起来不太好( OCD a>踢)。


  • 解决方案


    1. 这行可能看起来没有缩放,因为canvas在你的情况下有一个高分辨率的后备存储: http://www.html5rocks.com/en/tutorials/canvas/hidpi/


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


    3. 这取决于您的用例。如果无标度足够好,那就去做吧。否则,如果您需要对应用程序的DPI进行控制,请使用最高DPI方法。



    Recently I got into HTML canvas drawing and the retina support for it. Without further configuration lines drawn on a canvas-element look a little bit blurry on retina displays.

    I do understand that the retina display has four times as much pixels and therefore has to fill some of the device pixels by default (otherwise the picture would be only half the size intended to).

    Example:
    Draw an HTML canvas with width: 50px and height: 50px.

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

    The browser on a normal screen just draws it (50*50 pixels). The browser on a retina display receives the 50x50px canvas, but since it is retina 50*50 device pixels would be smaller then intended. Therefore the browser draws it 100*100 pixels on retina.

    A clear line (single pixel line black/white) on the canvas now becomes a little blurry, since the browser has to fill the nearby pixels and uses the nearby surrounding - some pixels turn out grey.

    How to fix it:
    Th piece of code should fix the problem:

    // 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)
    }
    

    What I think the code does:
    With this piece of code used on the canvas the browser is informed to use 50*50px (that is what the canvas.style is set to) as in the example above - 50*50px on normal screens, 100*100px on retinas. But it internally handles the canvas as an canvas of twice the size (at least on retina devices)and therefore is able to draw the pixels which are normally filled by the browser.

    The tricky part (I don't quite understand):
    The scaling. Double 'canvas.width'? Fine, now we have more pixels we can write to - more information. Good.
    But now it is scaled, therefore we don't really write to the extra pixel (only 0 - 50 will show up on the canvas) - who fills the device pixels this time? I tried it without the scaling and it allows me to draw thinner lines on retina (~1 device pixel) on the range 0 - 100 - these pixels are still a little bit blurry though, the scaled lines are thicker, but crystal clear. Fuzzy only visible with a lot of zoom.

    Pro scale:

    • crystal lines
    • No scale somehow didn't produce a strong black in my example (visible under strong zoom)

    Pro no scale:

    • ability to draw thin lines
    • canvas.width really represents the pixels I can write to. For example:

    context.moveTo(0, context.canvas.height/2);
    context.lineTo(context.canvas.width, context.canvas.height/2);
    

    works. This doesn't work with scaling, since context.canvas.width returns unscaled values.

    My questions:

    • Why is the line clear with scaling, even though I don't even fill the extra pixels by myself?
    • How would I go about the misleading return value?
    • Should I always use context.canvas.width / PIXEL_RATIO (with scaling)? This does fix the problem, but doesn't look nice in the code (OCD kicks in). I will go with this until I got something better though.

    解决方案

    1. The line might look clear without scaling because canvas has a high dpi backing store in your case: http://www.html5rocks.com/en/tutorials/canvas/hidpi/

    2. I don't understand the question about misleading return values. Everything seems perfectly consistent. Have you tried to set the line width to 0.5 in the "unscaled" case?

    3. It really depends on your use case. If "unscaled" is good enough, go for it. Otherwise, if you need control over DPI for your application, go for the high DPI approach.

    这篇关于了解HTML视网膜画布支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆