不同像素密度的Html Canvas

时间:2015-12-16 10:14:39

标签: javascript html5 html5-canvas retina-display

我希望有人可以提供帮助,因为我似乎无法找到可靠的解决方案。

是否有框架或常规设置可以很好地获取html画布,并且在不同的像素密度下具有正确的大小?

我理解为什么这个问题存在。我已经非常彻底地搜索了如此道歉,如果之前已经多次询问过,但我仍然没有看到一个强有力的解决方案。

附加:为了澄清,画布渲染在视网膜屏幕上看起来很模糊,我想有一种方法可以让渲染效果看起来很清晰,无论它们在哪里被观看。结构框架看起来很棒but their demos still look fuzzy on my retina screen.

4 个答案:

答案 0 :(得分:3)

fabricjs实现了一个缩放黑客,可以在屏幕上以及“逻辑像素”之间具有不同比例的屏幕上很好地渲染画布,

当你将你的问题标记为视网膜缩放时,我想你是在问这个问题。

如果你不想使用那个框架,这基本上就是它在纯javascript中的工作方式(或多或少的fabricjs的相同实现)

if( window.devicePixelRatio !== 1 ){
          var c = document.getElementById('mycanvas') // your canvas
          var w = c.width, h = c.height;

          // scale the canvas by window.devicePixelRatio
          c.setAttribute('width', w*window.devicePixelRatio);
          c.setAttribute('height', h*window.devicePixelRatio);

          // use css to bring it back to regular size
          c.setAttribute('style', 'width="'+w+'"; height="'+h+'";')

          // set the scale of the context
          c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
 }

请注意,浏览器必须启用视网膜。

请检查视网膜屏幕上的图像是否有所不同。 首先是视网膜启用,其次不是。 (请注意,可怕的图像)

var c = new fabric.StaticCanvas('canvas');
var c2 = new fabric.StaticCanvas('canvas2', {enableRetinaScaling: false});
fabric.Image.fromURL('http://www.free-desktop-backgrounds.net/free-desktop-wallpapers-backgrounds/free-hd-desktop-wallpapers-backgrounds/535693007.jpg', function(img) {
  img.scale(0.5);
  var circle = new fabric.Circle({radius: 40, fill: 'red', stroke: 'blue', top: 2, left: 2});
  
  c.add(img);
  c.add(circle);
  c2.add(img);
  c2.add(circle);
});
<script src="http://www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas id="canvas" width="800" height="600"></canvas>

<canvas id="canvas2" width="800" height="600"></canvas>

与其他图片链接: http://www.deltalink.it/andreab/fabric/retina.html

修改 添加了矢量几何形状以查看是否有更多证据。

答案 1 :(得分:2)

如果您查看,例如three.js source,它会实现如下调整大小:

this.setSize = function ( width, height, updateStyle ) {

        _width = width;
        _height = height;

        _canvas.width = width * pixelRatio;
        _canvas.height = height * pixelRatio;

        if ( updateStyle !== false ) {

            _canvas.style.width = width + 'px';
            _canvas.style.height = height + 'px';

        }

        this.setViewport( 0, 0, width, height );

    };

this.setViewport = function ( x, y, width, height ) {

        _viewportX = x * pixelRatio;
        _viewportY = y * pixelRatio;

        _viewportWidth = width * pixelRatio;
        _viewportHeight = height * pixelRatio;

        _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );

    };

_gl似乎是画布上下文。

看起来他们只是采用widthheight(例如屏幕宽度和高度)并将其乘以pixel ratio,这是一个介于1之间的整数-4据我所知。

答案 2 :(得分:0)

创建具有给定分辨率的画布

function createCanvas (width, height) {
    var canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    return canvas;
}
var canvas = createCanvas(1024,1024); // create a canvas that is 1024by1024 pixels

将其添加到元素

var element = document.getElementById("uniqueId");
if(element !== null){
   element.appendChild(canvas);
}

答案 3 :(得分:0)

这是解决具有较高dpi(devicePixelRatio)屏幕的模糊画布问题的技巧。

缩放画布元素尺寸:dpr x css尺寸。

这是dpr为2.0的样子

<canvas class="small" width="400" height="400"></canvas> 

CSS

.small {
    width: 200px;
    height: 200px;
}

使用Javascript检测 dpr 画布元素尺寸。

const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect(); // css

计算新尺寸

canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;

现在,您可以使用CSS类,@ media规则等来设置相对尺寸。 Javascript将检测元素大小和dpr,并返回正确的相对大小。