前一段时间组员有个项目,需要做大转盘抽奖,找来找去,网上找了个小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
标签中的宽高样式渲染,实际上就是缩小操作,缩小会让图片变的清晰,这时候图片或者文字都是清晰的。
修改前
修改后
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!