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);