微信小程序容许对普通元素经过 border-radius
的设置来进行圆角的绘制,但有时候在使用 canvas
绘图的时候,也须要圆角,例如须要将页面上某块区域导出为图片下载到本地的时候,经常使用的解决方法就是使用 canvas
将这块区域绘制出来,最后导出 canvas
便可,可是 canvas
没有直接提供圆角的绘制 api
,因此须要 曲线救国
git
圆角矩形与通常矩形的区别在于,前者的四个角都是圆弧,因此只须要将通常矩形的四个角切掉,换成圆弧便可,以下图就是一个通常矩形被切掉了四个角的样子:github
很明显,切掉了四个角的矩形,剩下其实就是四条 line
,既然如此,彻底能够跳过绘制矩形而后切角这一步,由于切角的结果就是四条边(line
),直接绘制四条边便可。 而后在每两条边的缺角处绘制弧度为 0.5 * Math.PI
的圆弧,最后这四条边与四个圆弧所封闭的图形就是圆角矩形:canvas
原理知道了,代码就很好写了,这里只说几个注意点:小程序
fillStyle
颜色设置为 transparent
想将封闭路径的图形绘制下来,须要调用 stroke
或 fill
方法,默认 stroke
或 fill
的颜色是 black
,可是这里有个问题, 圆弧的绘制可能会出现锯齿或者糊边,若是 stroke
或 fill
的颜色,与你所须要绘制的圆角矩形的边缘色调不一致,这种糊边的感受会比两者色调一致的更明显, 下图第一个为色调一致,第二个为色调不一致的状况:微信小程序
不过据我观测,只要不是特地放大仔细看,不管是色调是否一致,其实通常人很难注意到糊边的事情api
clip
绘制好了圆角选区以后,还须要调用 ctx.clip
方法来裁剪选区微信
save
与 restore
若是这个矩形选区只是 canvas
画布的一部分,为了不对后续的影响,最好在 beginPath
以前,将以前的动做 save
,而后画完后再 restore
ui
一个关于 在 canvas
上绘制圆角图片,并下载到本地 的可运行示例代码已经放到 github上了,注释也比较详细,须要的可自取spa
其中关键代码以下:3d
/** * * @param {CanvasContext} ctx canvas上下文 * @param {number} x 圆角矩形选区的左上角 x坐标 * @param {number} y 圆角矩形选区的左上角 y坐标 * @param {number} w 圆角矩形选区的宽度 * @param {number} h 圆角矩形选区的高度 * @param {number} r 圆角的半径 */
function roundRect(ctx, x, y, w, h, r) {
// 开始绘制
ctx.beginPath()
// 由于边缘描边存在锯齿,最好指定使用 transparent 填充
// 这里是使用 fill 仍是 stroke均可以,二选一便可
ctx.setFillStyle('transparent')
// ctx.setStrokeStyle('transparent')
// 左上角
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
// border-top
ctx.moveTo(x + r, y)
ctx.lineTo(x + w - r, y)
ctx.lineTo(x + w, y + r)
// 右上角
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
// border-right
ctx.lineTo(x + w, y + h - r)
ctx.lineTo(x + w - r, y + h)
// 右下角
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
// border-bottom
ctx.lineTo(x + r, y + h)
ctx.lineTo(x, y + h - r)
// 左下角
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
// border-left
ctx.lineTo(x, y + r)
ctx.lineTo(x + r, y)
// 这里是使用 fill 仍是 stroke均可以,二选一便可,可是须要与上面对应
ctx.fill()
// ctx.stroke()
ctx.closePath()
// 剪切
ctx.clip()
}
复制代码