Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 在所有设备上显示像素完美画布_Html_Html5 Canvas - Fatal编程技术网

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;
    }