加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

微信小程序 canvas圆角矩形的绘制

发布时间:2020-12-14 19:37:22 所属栏目:资源 来源:网络整理
导读:作者:?清夜 原文:https://juejin.im/post/5b7cecd7e51d4538e3318f27 微信小程序允许对普通元素通过? border-radius ?的设置来进行圆角的绘制,但有时候在使用? canvas ?绘图的时候,也需要圆角,例如需要将页面上某块区域导出为图片下载到本地的时候,常用

作者:?清夜

原文:https://juejin.im/post/5b7cecd7e51d4538e3318f27


微信小程序允许对普通元素通过?border-radius?的设置来进行圆角的绘制,但有时候在使用?canvas?绘图的时候,也需要圆角,例如需要将页面上某块区域导出为图片下载到本地的时候,常用的解决方法就是使用?canvas?将这块区域绘制出来,最后导出?canvas?即可,但是?canvas?没有直接提供圆角的绘制?api?,所以需要?曲线救国

圆角矩形与一般矩形的区别在于,前者的四个角都是圆弧,所以只需要将一般矩形的四个角切掉,换成圆弧即可,如下图就是一个一般矩形被切掉了四个角的样子:

很明显,切掉了四个角的矩形,剩下其实就是四条?line?,既然如此,完全可以跳过绘制矩形然后切角这一步,因为切角的结果就是四条边(?line?),直接绘制四条边即可。 然后在每两条边的缺角处绘制弧度为?0.5 * Math.PI?的圆弧,最后这四条边与四个圆弧所封闭的图形就是圆角矩形:

原理知道了,代码就很好写了,这里只说几个注意点:

  • 封闭图形的?fillStyle?颜色设置为?transparent

想将封闭路径的图形绘制下来,需要调用?stroke?或?fill?方法,默认?fill?的颜色是?black?,但是这里有个问题, 圆弧的绘制可能会出现锯齿或者糊边,如果?fill的颜色,与你所需要绘制的圆角矩形的边缘色调不一致,这种糊边的感觉会比二者色调一致的更明显, 下图第一个为色调一致,第二个为色调不一致的情况:

不过据我观测,只要不是特意放大仔细看,无论是色调是否一致,其实一般人很难注意到糊边的事情

  • clip

绘制好了圆角选区之后,还需要调用?ctx.clip?方法来裁剪选区

  • save?与?restore

如果这个矩形选区只是?canvas?画布的一部分,为了避免对后续的影响,最好在?beginPath?之前,将之前的动作?save?,然后画完后再?restore

一个关于?在?canvas?上绘制圆角图片,并下载到本地?的可运行示例代码已经放到?github?上了,注释也比较详细,需要的可自取

其中关键代码如下:

/**
  * 
  * @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都可以,二选一即可
  .setFillStyle('transparent')
  // ctx.setStrokeStyle('transparent')
  // 左上角
  .arc(x + r,y + r,r,Math.PI,Math.PI * 1.5)

  // border-top
  .moveTo(x + r,y)
  .lineTo(x + w - r,0);">.lineTo(x + w,y + r)
  // 右上角
  .arc(x + w - r,0);">1.5,0);">2)

  // border-right
  // 右下角
  0,0);">0.5)

  // border-bottom
  .lineTo(x + r,y + h)
  .lineTo(x,y + h - r)
  // 左下角
  0.5,Math.PI)

  // border-left
  // 这里是使用 fill 还是 stroke都可以,二选一即可,但是需要与上面对应
  .fill()
  // ctx.stroke()
  .closePath()
  // 剪切
  .clip()
}
复制代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读