From 0baa0db6d35b73726588f4918de72f56a2ebdbf2 Mon Sep 17 00:00:00 2001 From: 0JARVIS0 <709406687@qq.com> Date: Tue, 19 Nov 2019 17:16:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=86=E5=88=AB=E5=AE=9A?= =?UTF-8?q?=E4=B9=89radius=EF=BC=8C=E4=BF=AE=E5=A4=8DborderRadius=E4=B8=BA?= =?UTF-8?q?0=E6=97=B6=E4=B8=8D=E6=AD=A3=E5=B8=B8=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pen.js | 76 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/lib/pen.js b/lib/pen.js index 9de321e..857e7e7 100644 --- a/lib/pen.js +++ b/lib/pen.js @@ -81,25 +81,52 @@ export default class Painter { } } + _doRadius(borderRadius, width, height, borderWidth = '0') { + let r1 = 0, + r2 = 0, + r3 = 0, + r4 = 0 + if (borderRadius) { + const border = borderRadius.split(' ') + if (border.length === 1) { + r1 = r2 = r3 = r4 = Math.min(borderRadius === '0' ? 0 : borderRadius.toPx(), width / 2, height / 2); + } else if (border.length === 4) { + r1 = Math.min(border[0] === '0' ? 0 : border[0].toPx(), width / 2, height / 2); + r2 = Math.min(border[1] === '0' ? 0 : border[1].toPx(), width / 2, height / 2); + r3 = Math.min(border[2] === '0' ? 0 : border[2].toPx(), width / 2, height / 2); + r4 = Math.min(border[3] === '0' ? 0 : border[3].toPx(), width / 2, height / 2); + } + } + const lineWidth = borderWidth === '0' ? 0 : borderWidth.toPx(); + this.ctx.lineWidth = lineWidth; + const points = [ + [r2 === 0 ? width / 2 + lineWidth / 2 : width / 2 - r2, -height / 2 - lineWidth / 2], + [width / 2 + lineWidth / 2, r3 === 0 ? height / 2 + lineWidth / 2 : height / 2 - r3], + [r4 === 0 ? -width / 2 - lineWidth / 2 : -width / 2 + r4, height / 2 + lineWidth / 2], + [-width / 2 - lineWidth / 2, r1 === 0 ? -height / 2 - lineWidth / 2 : -height / 2 + r1] + ] + this.ctx.beginPath(); + r1 !== 0 && this.ctx.arc(-width / 2 + r1, -height / 2 + r1, r1 + lineWidth / 2, 1 * Math.PI, 1.5 * Math.PI); //左上角圆弧 + this.ctx.lineTo(...points[0]); + r2 !== 0 && this.ctx.arc(width / 2 - r2, -height / 2 + r2, r2 + lineWidth / 2, 1.5 * Math.PI, 2 * Math.PI); // 右上角圆弧 + this.ctx.lineTo(...points[1]); + r3 !== 0 && this.ctx.arc(width / 2 - r3, height / 2 - r3, r3 + lineWidth / 2, 0, 0.5 * Math.PI); // 右下角圆弧 + this.ctx.lineTo(...points[2]); + r4 !== 0 && this.ctx.arc(-width / 2 + r4, height / 2 - r4, r4 + lineWidth / 2, 0.5 * Math.PI, 1 * Math.PI); // 左下角圆弧 + this.ctx.lineTo(...points[3]); + this.ctx.closePath(); + } + /** * 根据 borderRadius 进行裁减 */ _doClip(borderRadius, width, height) { if (borderRadius && width && height) { - const r = Math.min(borderRadius.toPx(), width / 2, height / 2); // 防止在某些机型上周边有黑框现象,此处如果直接设置 fillStyle 为透明,在 Android 机型上会导致被裁减的图片也变为透明, iOS 和 IDE 上不会 // globalAlpha 在 1.9.90 起支持,低版本下无效,但把 fillStyle 设为了 white,相对默认的 black 要好点 this.ctx.globalAlpha = 0; this.ctx.fillStyle = 'white'; - this.ctx.beginPath(); - this.ctx.arc(-width / 2 + r, -height / 2 + r, r, 1 * Math.PI, 1.5 * Math.PI); - this.ctx.lineTo(width / 2 - r, -height / 2); - this.ctx.arc(width / 2 - r, -height / 2 + r, r, 1.5 * Math.PI, 2 * Math.PI); - this.ctx.lineTo(width / 2, height / 2 - r); - this.ctx.arc(width / 2 - r, height / 2 - r, r, 0, 0.5 * Math.PI); - this.ctx.lineTo(-width / 2 + r, height / 2); - this.ctx.arc(-width / 2 + r, height / 2 - r, r, 0.5 * Math.PI, 1 * Math.PI); - this.ctx.closePath(); + this._doRadius(borderRadius, width, height) this.ctx.fill(); // 在 ios 的 6.6.6 版本上 clip 有 bug,禁掉此类型上的 clip,也就意味着,在此版本微信的 ios 设备下无法使用 border 属性 if (!(getApp().systemInfo && @@ -128,24 +155,8 @@ export default class Painter { } this.ctx.save(); this._preProcess(view, true); - let r; - if (borderRadius) { - r = Math.min(borderRadius.toPx(), width / 2, height / 2); - } else { - r = 0; - } - const lineWidth = borderWidth.toPx(); - this.ctx.lineWidth = lineWidth; this.ctx.strokeStyle = (borderColor || 'black'); - this.ctx.beginPath(); - this.ctx.arc(-width / 2 + r, -height / 2 + r, r + lineWidth / 2, 1 * Math.PI, 1.5 * Math.PI); - this.ctx.lineTo(width / 2 - r, -height / 2 - lineWidth / 2); - this.ctx.arc(width / 2 - r, -height / 2 + r, r + lineWidth / 2, 1.5 * Math.PI, 2 * Math.PI); - this.ctx.lineTo(width / 2 + lineWidth / 2, height / 2 - r); - this.ctx.arc(width / 2 - r, height / 2 - r, r + lineWidth / 2, 0, 0.5 * Math.PI); - this.ctx.lineTo(-width / 2 + r, height / 2 + lineWidth / 2); - this.ctx.arc(-width / 2 + r, height / 2 - r, r + lineWidth / 2, 0.5 * Math.PI, 1 * Math.PI); - this.ctx.closePath(); + this._doRadius(borderRadius, width, height, borderWidth) this.ctx.stroke(); this.ctx.restore(); } @@ -599,16 +610,7 @@ export default class Painter { this.ctx.fillStyle = view.css.color; } const borderRadius = view.css.borderRadius - const r = borderRadius ? Math.min(borderRadius.toPx(), width / 2, height / 2) : 0; - this.ctx.beginPath(); - this.ctx.arc(-width / 2 + r, -height / 2 + r, r, 1 * Math.PI, 1.5 * Math.PI); //左上角圆弧 - this.ctx.lineTo(width / 2 - r, -height / 2); - this.ctx.arc(width / 2 - r, -height / 2 + r, r, 1.5 * Math.PI, 2 * Math.PI); // 右上角圆弧 - this.ctx.lineTo(width / 2, height / 2 - r); - this.ctx.arc(width / 2 - r, height / 2 - r, r, 0, 0.5 * Math.PI); // 右下角圆弧 - this.ctx.lineTo(-width / 2 + r, height / 2); - this.ctx.arc(-width / 2 + r, height / 2 - r, r, 0.5 * Math.PI, 1 * Math.PI); // 左下角圆弧 - this.ctx.closePath(); + this._doRadius(borderRadius, width, height) this.ctx.fill(); this.ctx.restore(); this._doBorder(view, width, height);