支持分别定义radius,修复borderRadius为0时不正常显示问题

This commit is contained in:
0JARVIS0 2019-11-19 17:16:37 +08:00
parent 6caffeb998
commit 0baa0db6d3

View File

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