- html/
- Html 在所有设备上显示像素完美画布
Html 在所有设备上显示像素完美画布
Html 在所有设备上显示像素完美画布,html,html5-canvas,Html,Html5 Canvas,我有一些画布,我想在每一个(现代)浏览器中显示像素完美。默认情况下,具有高DPI屏幕的设备正在缩放我的页面,以便所有内容看起来都是正确的大小,但它正在破坏我画布的外观
如何确保画布中的一个像素=屏幕上的一个像素?最好这不会影响页面上的其他元素,因为我仍然希望文本能够根据设备进行适当的缩放
我已经尝试根据window.devicePixelRatio设置画布尺寸的样式。这使得画布的大小合适,但内容看起来更糟。我猜这只是在它们已经被错误地放大之后再缩小
*如果你介意的话,因为画布使用抖动,浏览器正在
我有一些画布,我想在每一个(现代)浏览器中显示像素完美。默认情况下,具有高DPI屏幕的设备正在缩放我的页面,以便所有内容看起来都是正确的大小,但它正在破坏我画布的外观
如何确保画布中的一个像素=屏幕上的一个像素?最好这不会影响页面上的其他元素,因为我仍然希望文本能够根据设备进行适当的缩放
我已经尝试根据window.devicePixelRatio
设置画布尺寸的样式。这使得画布的大小合适,但内容看起来更糟。我猜这只是在它们已经被错误地放大之后再缩小
*如果你介意的话,因为画布使用抖动,浏览器正在执行某种lerp而不是最近邻,所以很容易:
canvas {
image-rendering: pixelated;
image-rendering: crisp-edges;
}
浏览器支持不是很好,但到目前为止,我测试过的所有现代浏览器都支持它,所以我很高兴。我已经在Windows、Mac、Linux、iOS和Android上用Chrome、Firefox和Safari进行了测试
只要画布以正常大小显示,这对正常DPI设备没有影响。此外,根据屏幕的不同,在高DPI设备上会出现有趣的瑕疵,但我认为这是不可避免的,因为这些显示器是如何工作的。它们仍然比没有样式的工件要好
我还尝试用javascript将我所有的画布放大200%,然后将它们设置为普通大小div的背景图像。这就是苹果公司建议为视网膜设备显示图像的方式,所以我认为这会产生很大的效果。但最终还是会出现瑕疵,而且这些瑕疵并不是通过放大页面来修复的,因此实际上比上面的简单解决方案更糟糕。对我来说,只有不同的“像素完美”技术组合才有助于归档结果:
以像素比例获取并缩放画布:
pixelRatio=window.devicePixelRatio/ctx.backingStorePixelRatio
在调整大小时缩放画布(避免画布默认拉伸缩放)
将线宽与pixelRatio相乘,以找到合适的“真实”像素线宽:
context.lineWidth=厚度*像素比率强>
注意:不确定它是否对所有设备有效
检查线的厚度是奇数还是偶数。将像素比率的一半添加到奇数厚度值的线位置
x=x+像素比率/2强>
<奇数行将被放置在像素的中间。上面这条线是用来稍微移动它的
使用图像渲染:像素化李>
函数getPixelRatio(上下文){
dpr=window.devicePixelRatio | | 1,
bsr=context.webkitBackingStorePixelRatio||
context.mozBackingStorePixelRatio||
context.msBackingStorePixelRatio||
context.obackStorePixelRatio||
context.backingStorePixelRatio | | 1;
返回dpr/bsr;
}
var canvas=document.getElementById('canvas');
var context=canvas.getContext(“2d”);
var pixelRatio=getPixelRatio(上下文);
var initialWidth=canvas.clientWidth*像素比率;
var initialHeight=canvas.clientHeight*像素比率;
window.addEventListener('resize',函数(args){
重新缩放();
重画();
},假);
函数重缩放(){
变量宽度=初始宽度*像素比率;
变量高度=初始高度*像素比率;
if(宽度!=context.canvas.width)
context.canvas.width=宽度;
if(高度!=context.canvas.height)
context.canvas.height=高度;
setTransform(像素比率,0,0,像素比率,0,0);
}
函数像素线(x1,y1,x2,y2){
context.save();
context.beginPath();
厚度=1;
//将笔划厚度乘以像素比例!
context.lineWidth=厚度*像素比率;
context.strokeStyle=“黑色”;
moveTo(getSharpPixel(厚度,x1),getSharpPixel(厚度,y1));
lineTo(getSharpPixel(厚度,x2),getSharpPixel(厚度,y2));
stroke();
restore();
}
函数像素完美矩形(x、y、w、h、厚度、useDash){
context.save();
//像素完美矩形:
context.beginPath();
//将笔划厚度乘以像素比例!
context.lineWidth=厚度*像素比率;
context.strokeStyle=“红色”;
如果(使用dash){
context.setLineDash([4]);
}
//使用锐利的x,y和整数w,h!
context.strokeRect(
getSharpPixel(厚度,x),
getSharpPixel(厚度,y),
数学地板(w),
(h)层;
restore();
}
函数重画(){
clearRect(0,0,canvas.width,canvas.height);
像素线(50,50250);
像素线(120,0120250);
像素线(122,0122250);
像素完美矩形(10,11,200.3,43.2,1,false);
像素完美矩形(41,42,150.3,43.2,1,真);
像素完美矩形(102100150.3243.2,2,真);
}
功能getSharpPixel(厚度,位置){
如果(厚度%2==0){
返回pos;
}
返回pos+pixelRatio/2;
}
重新缩放();
重画()代码>
画布{
图像渲染:-moz清晰的边缘;
图像渲染:-webkit清晰的边缘;
图像渲染:像素化;
图像渲染:清晰的边缘;
宽度:100vh;
高度:100vh;
}