阅读 395

canvas移动端画图出现锯齿如何解决(canvas画线去掉锯齿)

前一段时间组员有个项目,需要做大转盘抽奖,找来找去,网上找了个小demo,底层是用canvas画的,本来我们想在前端实现按中奖比例的随机抽奖行为,测试已经实现了,但是后端开发同事自告奋勇说:不用,我们接口传给你中奖奖品信息。好,????,我就喜欢这么干脆利落,说干就干,转盘功能很快实现了,提测,上线。

到了产品验收环节,亲爱的产品同事揪着一个小问题始终不放,本来不影响主流程,功能已经很哇塞了,但是产品要改,我们只能硬着头皮继续啃代码。

我们遇到的这个问题就是:移动端canvas画图片时边缘有一圈锯齿,图片也模糊难辨,文字也有这个问题。

ok,问题清楚了,下面开始找解决方案,网上搜了很多,最后总结如下:

出现这个问题的原因应该是手机的宽是720px的, 而这个canvas是按照小于720px画出来的, 所以在720px的手机上显示时, 这个canvas的内容其实是经过拉伸的, 所以会出现模糊和锯齿.

解决这个问题,网上主流的有两种方案:

第一种,设置样式解决。

在绘制的过程中画布内容的实际大小是根据 canvas 的 width 与 height 属性设置的,而 style 或者CSS设置的width 与 height 只是简单的对画布进行缩放。

canvas相当于一个 img ,其中画布的 width 与 height 属性,相当于 img 中图片的原始尺寸;我们使用JS在画布上绘制的内容对应的就是 img 中的图片;而 style 或者CSS设置的 width 与 height ,就是设置 canvas 或者 img 在页面上要显示的大小。

解决模糊的做法,就是将这张“图片”变得高清一点,然后缩小了来显示。

<canvas width="200" height="400" style="width: 100px;height: 200px;"></canvas>复制代码

相当于画了一张200*400的图片,然后设置他显示成100*200的大小,这样一来就变得清晰了。

注意:将画布放大之后,绘制的过程中对应的那些坐标,长度等等都要相应的放大。

这种方案多见于2018年以前的文章,2018年以后大都推荐使用另外一种方案。

第二种,使用window.devicePixelRatio

使用window.devicePixelRatio设备上物理像素和设备独立像素(device-independent pixels (dips))的比例来设置canvas实际需要放大的倍数,原理与第一种方法一样,区别在于devicePixelRatio取出的是实际的比例倍数,在pc端显示为1,移动端各不相同,我在iphone上看是3。

核心代码:

// 真正核心代码
let devicePixelRatio = 1
if (window.devicePixelRatio) {
    devicePixelRatio = window.devicePixelRatio
    _this.style.width = width + "px";
    _this.style.height = height + "px";
    _this.height = height * devicePixelRatio;
    _this.width = width * devicePixelRatio;
}
// 下面是应用代码
ctx.lineWidth = 290 * devicePixelRatio;
ctx.arc(0, 0, 104 * devicePixelRatio, startAngel, endAngel)
// 核心代码
ctx.scale(devicePixelRatio, devicePixelRatio);复制代码

上面代码的核心思路就是,首先获取到设备对应的devicePixelRatio,这个就是我们在画图,画面,写字的时候的放大倍数,只要是绘画过程中有长度单位,都要放大这个倍数,一个绘画操作完成后,需要调用ctx.scale(devicePixelRatio, devicePixelRatio);,将画布放大,这时候我们绘画以及画布的实际大小就被放大了,等到渲染的时候,js再根据我们设置在canvas标签中的宽高样式渲染,实际上就是缩小操作,缩小会让图片变的清晰,这时候图片或者文字都是清晰的。

修改前

qian.png

修改后

hou.png


作者:yourbusiness_
链接:https://juejin.cn/post/7031001865479258120


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐