共计 1372 个字符,预计需要花费 4 分钟才能阅读完成。
场景
在挪动端通过 H5 的 canvas 标签绘制图表的时候,不通过任何解决的图表相比拟其余元素看起来会有些含糊。
序
先看上面一组高分屏下的圆,下面是一般 div 元素“绘制”的圆,上面是通过 canvas
绘制的圆。能够看出,上面的圆相比拟是含糊的。
为什么会这样?
一台一般屏幕上的像素(逻辑像素),能够当做是失常的像素(css 中设置的像素),当画一个 100px 的元素,他就是一个 100px 的元素。
然而,在呈现了一些高分辨率的屏幕之后,就产生了一些变动。随之也呈现了一个属性 devicePixelRatio
,它容许咱们去查问设施屏幕的像素比。高分屏下(假如 devicePixelRatio 为 3),在 css 设置的 100px(逻辑像素 ),理论渲染的是 300px 的 物理像素。
而不论是否为高分屏,canvas 中的单位 1(逻辑像素),就是 1 物理像素,所以在高分屏下,canvas 绘制的图片看起来就含糊了(能够设想成,一张清晰度失常的一般图片为了布满整个背景被强行放大 n 倍,所以看起来含糊了)。
如何解决?
这个波及到 canvas 标签的一些个性。即 canvas 元素的大小(宽高)会影响 canvas 画布的内容。
举个栗子:
画一个半径为 50 的圆,画布默认宽高为 300 * 150,不设置 canvas 元素宽高的状况下是一个圆;如果设置 canvas 元素的宽高都为 150,那么画布 x 轴方向的内容会被压缩,为原来的 1/2 倍。
那么,利用这个个性。
思路: 高分屏下(假如 devicePixelRatio 为 3,逻辑像素为 100px),将 canvas 画布大小 [乘以 3] 转换成理论像素(物理像素)大小,而后通过 css 设置 canvas 元素的大小 为逻辑像素大小 [100px]。缩放后,画布内容就是高清的了。然而这个时候画布内容是放大的,这个时候能够应用 canvas 的 scale()
去进行放大 3 倍就能够了。
正文:canvas 的
scale()
的办法在 放大 / 放大 canvas 时,不会扭转内容素质,能够了解为清晰度不会变。
实现解读
参考图片:一张一般的图片,为了占满背景,被强行放大,导致有点含糊。为了显示更清晰,那么就设置更小的宽高。然而为了占满背景,就又进行一次不会扭转图片素质的等比放大。
代码实现
// 仅练习
class DprCanvas {constructor(id) {const canvas = document.getElementById(id)
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio
const logicalWidth = canvas.width
const logicalHeight = canvas.height
canvas.width = logicalWidth * dpr
canvas.height = logicalHeight * dpr
canvas.style.width = logicalWidth + 'px'
canvas.style.height = logicalHeight + 'px'
ctx.scale(dpr, dpr)
this.draw(ctx)
}
draw(ctx) {ctx.beginPath()
ctx.fillStyle = 'darkcyan'
ctx.arc(50, 50, 50, 0, Math.PI * 2)
ctx.fill()}
}
成果