当前位置: 首页 > 科技观察

图形编辑器:适配高分辨率屏幕

时间:2023-03-18 21:29:30 科技观察

大家好,我是前端西瓜哥。我的图形编辑器项目一直是使用旧的1080P显示器开发的。但是当我最近切换到MacbookPro的Retina屏幕开发时,我发现高分辨率屏幕(high-resolutionscreen)使图形编辑器中的线条变得模糊。这次我们将看看如何解决这个问题。项目地址,欢迎star:https://github.com/F-star/suika在线体验:https://blog.fstars.wang/app/suika/高分辨率屏幕中的一个像素表情代码(独立像素),本来只需要一块屏幕的一个发光单元(物理像素),一对一的关系很好理解。但是随着显示器的发展,我们有了更小尺寸的发光单元,原来一个发光单元的空间可以放置更多的小发光单元。在这种情况下,如果一个发光单元对应代码中的一个像素点,绘制出来的图形就会变小,从远处看也看不清楚。怎么办,我们的方案是在一个代码中用多个光单元来表示一个像素。比如Mac的视网膜(Retina)屏幕,会将独立像素的宽高乘以2,映射到4个发光单元。但是并不是一定要把多个点都设置成同一种颜色,而是在某些情况下要做抗锯齿,所以你会发现在高分辨率屏幕上锯齿更少,看起来更高清,但也会让最初想要平滑锯齿状的边缘。devicePixelRatiodevicePixelRatio(通常我们使用dpr变量名)是设备像素比,指的是当前显示设备的物理像素分辨率与CSS像素分辨率的比值。这个定义有点抽象,但其实就是我前面说的。对于Mac的视网膜(Retina)屏幕,其devicePixelRatio为2,即一个CSS像素的宽高乘以2绘制到屏幕的4个发光单元上。我们可以通过window.devicePixelRatio获取浏览器所在屏幕的设备像素比。Canvas处理Canvas绘制的像素(比如线条)会因为在高分辨率屏幕中被绘制成4个点(即发光单元)而变粗,同时也会因为抗锯齿处理而变得模糊。在IOSApp的UI设计中,有一个@2x、@3x的图形概念。就是将图片放大2倍、3倍进行设计,然后在渲染时指定尺寸回到原来的尺寸进行绘制。这样在渲染画面的时候可以得到更多的像素细节,让一个像素对应一个发光单元,而不是在1x1像素的基础上放大到2x2或者3x3,丢失细节。Canvas本质上是一张图片,它的width和height属性代表图片的原始宽高,style.width和style.height是实际Render的宽高。所以解决方法是将Canvas原来的宽高设置为devicePixelRatio乘以容器的宽度,然后用style.width和style.height设置容器的宽高。然后Canvas在绘制图形之前通过缩放和变形将缩小的Canvas恢复到原来的大小。constdpr=window.devicePixelRatio||1;constcw=1000;//容器的宽高,画布会覆盖容器区域。constch=1000;/***设置画布属性***/canvas.width=cw*dpr;canvas.height=ch*dpr;canvas.style.width=cw+'px';canvas.style.height=ch+'px';/***Draw***///因为Canvas的内容缩小了,在绘制图形之前,需要缩放dpr倍数才能变回原来的样子大小ctx.scale(dpr,dpr);//绘制每一个总结在这种图形的最后,高分辨率的屏幕发光单元更小。通常使用2x2或3x3的点来表示一个像素。在某些情况下,锯齿状的边缘会变得平滑,但也可能使清晰的线条边缘变得模糊。对于图片和Canvas,可以将对应的devicePixelRatio放大倍数,然后缩放到页面中容器的大小,这样显示就可以获得完整的像素信息,不会因为放大而失真。