Canvas 模糊问题解析和解决
前言
在最近的工作中,需要用到 canvas 绘制图形,一开始在电脑开发的时候效果很不错,可是页面一放到手机上显示就模糊了????,这是为什呢?????
问题复现
上面两个圆圈,左边是 canvas 绘制的,右边是 css 绘制的,可以明显看出 canvas 绘制的圆圈特别模糊
CODE
const canvas = document.getElementById('canvas') ctx = canvas.getContext('2d') ctx.beginPath() ctx.fillStyle = 'darkcyan' ctx.arc(80, 80, 80, 0, Math.PI * 2) ctx.stroke() 复制代码
原因解析
首先我需要了解一个属性 devicePixelRatio
屏幕像素比
在高清显示屏出现之前,比如屏幕宽度为1000px 那么其宽度上的物理像素也是1000px,而在高清屏出现之后,屏幕宽度为 1000px 时,物理像素有可能达到 2000px 或者更高
为了方便查询物理像素和屏幕像素的比值,在 window 对象上增加了一个属性 devicePixelRatio
来表示这个比值。
比如在 devicePixelRatio
为2的设备上,当我们使用 CSS 绘制一条 1px 的线时,为了保证绘制的大小,物理像素实际上会使用 2px 来绘制这一条线,而这样的转换是浏览器自动处理的,所以对开发者来说并没有太大的困扰
那么上面既然说了浏览器在渲染的时候会自动处理像素比的问题,CSS 绘制的图像经过转换之后不会出现模糊的问题,但 canvas 上怎么就出现了呢?
因为在 canvas 标签上定义的 width
和 height
的值并不会被转换,100px 就会被渲染成 100px 的物理像素,但是设备要求的是 200px,这时浏览器只能智能地填充像素之间的空白,以适应要求的大小。这就是 canvas 绘制的图片出现模糊的原因
解决方案
第一步:获取像素比
第二步:将 canvas 标签上的宽高属性设置为 显示大小 * 像素比
第三步:将 canvas 样式宽高设置为 显示大小
第四步:使用
scale
方法设置比值第五步:绘制 canvas 图形
function createHDCanvas (canvas, w, h) { const ratio = window.devicePixelRatio || 1; canvas.width = w * ratio; // 实际渲染像素 canvas.height = h * ratio; // 实际渲染像素 canvas.style.width = `${w}px`; // 控制显示大小 canvas.style.height = `${h}px`; // 控制显示大小 const ctx = canvas.getContext('2d') ctx.scale(ratio, ratio) // canvas 绘制 return canvas; } 复制代码
最终效果
这是上面的例子按照解决方法实现的效果
作者:李彦辉Jacky
链接:https://juejin.cn/post/7014765000916992036