Html Canvas 在不同的像素密度下
Html Canvas at varying pixel densities
我希望有人能帮助解决这个问题,因为我似乎找不到可靠的解决方案。
是否有一个框架或一般设置可以使 html canvas 渲染得很好,并且在不同的像素密度下以正确的大小呈现?
我明白为什么会出现这个问题。我已经进行了非常彻底的搜索,如果之前曾多次询问过这个问题,我深表歉意,但我仍然没有看到可靠的解决方案。
补充:为了澄清,canvas 渲染在视网膜屏幕上看起来很模糊,我想有一种方法可以让渲染看起来清晰,无论它们在哪里被查看。 fabric 框架看起来很棒 but their demos still look fuzzy on my retina screen.
如果你看一下,例如 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
似乎是 canvas 上下文。
他们似乎只是将 width
和 height
(例如屏幕宽度和高度)与 pixel ratio
相乘,它是介于两者之间的某个整数据我所知像1-4。
创建具有给定分辨率的 canvas
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);
}
fabricjs 实现了缩放 hack 以在屏幕上的像素与 "logic pixels"、
之间的不同比率的屏幕上很好地呈现 canvas
当您将问题标记为视网膜缩放时,我想您是在问这个问题。
如果您不想使用该框架,这基本上就是它在纯 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);
}
请注意,浏览器必须支持 Retina。
请检查这些图像在您的视网膜屏幕上看起来是否不同。
首先是启用视网膜,其次不是。
(注意,可怕的图像)
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>
Link配其他图片:
http://www.deltalink.it/andreab/fabric/retina.html
编辑:
加了一个矢量几何形状,看看有没有更多的证据。
这是解决更高 dpi (devicePixelRatio) 屏幕模糊 canvas 问题的技巧。
缩放 canvas 元素维度:dpr x css 维度。
这是 2.0 的 dpr 的样子
<canvas class="small" width="400" height="400"></canvas>
CSS
.small {
width: 200px;
height: 200px;
}
使用Javascript检测dpr和canvas元素尺寸。
const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect(); // css
计算新维度
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
现在可以使用CSS类、@media rules等设置相对尺寸。 Javascript 将检测元素大小和 dpr 以及 return 正确的相对大小。
我希望有人能帮助解决这个问题,因为我似乎找不到可靠的解决方案。
是否有一个框架或一般设置可以使 html canvas 渲染得很好,并且在不同的像素密度下以正确的大小呈现?
我明白为什么会出现这个问题。我已经进行了非常彻底的搜索,如果之前曾多次询问过这个问题,我深表歉意,但我仍然没有看到可靠的解决方案。
补充:为了澄清,canvas 渲染在视网膜屏幕上看起来很模糊,我想有一种方法可以让渲染看起来清晰,无论它们在哪里被查看。 fabric 框架看起来很棒 but their demos still look fuzzy on my retina screen.
如果你看一下,例如 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
似乎是 canvas 上下文。
他们似乎只是将 width
和 height
(例如屏幕宽度和高度)与 pixel ratio
相乘,它是介于两者之间的某个整数据我所知像1-4。
创建具有给定分辨率的 canvas
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);
}
fabricjs 实现了缩放 hack 以在屏幕上的像素与 "logic pixels"、
之间的不同比率的屏幕上很好地呈现 canvas当您将问题标记为视网膜缩放时,我想您是在问这个问题。
如果您不想使用该框架,这基本上就是它在纯 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);
}
请注意,浏览器必须支持 Retina。
请检查这些图像在您的视网膜屏幕上看起来是否不同。 首先是启用视网膜,其次不是。 (注意,可怕的图像)
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>
Link配其他图片: http://www.deltalink.it/andreab/fabric/retina.html
编辑: 加了一个矢量几何形状,看看有没有更多的证据。
这是解决更高 dpi (devicePixelRatio) 屏幕模糊 canvas 问题的技巧。
缩放 canvas 元素维度:dpr x css 维度。
这是 2.0 的 dpr 的样子
<canvas class="small" width="400" height="400"></canvas>
CSS
.small {
width: 200px;
height: 200px;
}
使用Javascript检测dpr和canvas元素尺寸。
const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect(); // css
计算新维度
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
现在可以使用CSS类、@media rules等设置相对尺寸。 Javascript 将检测元素大小和 dpr 以及 return 正确的相对大小。