支持边框dashed,可自定义虚线规格

This commit is contained in:
0JARVIS0 2019-11-19 19:22:14 +08:00
parent 0baa0db6d3
commit 06aaead258

View File

@ -81,7 +81,7 @@ export default class Painter {
}
}
_doRadius(borderRadius, width, height, borderWidth = '0') {
_border({ borderRadius = '0', width, height, borderWidth = '0', borderStyle = 'solid' }) {
let r1 = 0,
r2 = 0,
r3 = 0,
@ -99,34 +99,48 @@ export default class Painter {
}
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]
]
if (borderStyle === 'dashed') {
this.ctx.setLineDash([2 * lineWidth, 2 * lineWidth]);
} else if (borderStyle === 'dotted') {
this.ctx.setLineDash([lineWidth, lineWidth]);
} else if (borderStyle !== 'solid') {
const segments = borderStyle.split(/\s+/)
if (segments.length === 2) {
this.ctx.setLineDash([segments[0].toPx(), segments[1].toPx()])
}
}
const notSolid = borderStyle !== 'solid'
this.ctx.beginPath();
notSolid && r1 === 0 && this.ctx.moveTo(-width / 2 - lineWidth / 2, -height / 2 - lineWidth / 2) // 顶边虚线规避重叠规则
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]);
this.ctx.lineTo(r2 === 0 ? notSolid ? width / 2 : width / 2 + lineWidth / 2 : width / 2 - r2, -height / 2 - lineWidth / 2); // 顶边线
notSolid && r2 === 0 && this.ctx.moveTo(width / 2 + lineWidth / 2, -height / 2 - lineWidth / 2) // 右边虚线规避重叠规则
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]);
this.ctx.lineTo(width / 2 + lineWidth / 2, r3 === 0 ? notSolid ? height / 2 : height / 2 + lineWidth / 2 : height / 2 - r3); // 右边线
notSolid && r3 === 0 && this.ctx.moveTo(width / 2 + lineWidth / 2, height / 2 + lineWidth / 2) // 底边虚线规避重叠规则
r3 !== 0 && this.ctx.arc(width / 2 - r3, height / 2 - r3, r3 + lineWidth / 2, 0, 0.5 * Math.PI); // 右下角圆弧
this.ctx.lineTo(...points[2]);
this.ctx.lineTo(r4 === 0 ? notSolid ? -width / 2 : -width / 2 - lineWidth / 2 : -width / 2 + r4, height / 2 + lineWidth / 2); // 底边线
notSolid && r4 === 0 && this.ctx.moveTo(-width / 2 - lineWidth / 2, height / 2 + lineWidth / 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.lineTo(-width / 2 - lineWidth / 2, r1 === 0 ? notSolid ? -height / 2 : -height / 2 - lineWidth / 2 : -height / 2 + r1); // 左边线
this.ctx.closePath();
}
/**
* 根据 borderRadius 进行裁减
*/
_doClip(borderRadius, width, height) {
_doClip(borderRadius, width, height, borderStyle) {
if (borderRadius && width && height) {
// 防止在某些机型上周边有黑框现象,此处如果直接设置 fillStyle 为透明,在 Android 机型上会导致被裁减的图片也变为透明, iOS 和 IDE 上不会
// globalAlpha 在 1.9.90 起支持,低版本下无效,但把 fillStyle 设为了 white相对默认的 black 要好点
this.ctx.globalAlpha = 0;
this.ctx.fillStyle = 'white';
this._doRadius(borderRadius, width, height)
this._border({ borderRadius, width, height, borderStyle })
this.ctx.fill();
// 在 ios 的 6.6.6 版本上 clip 有 bug禁掉此类型上的 clip也就意味着在此版本微信的 ios 设备下无法使用 border 属性
if (!(getApp().systemInfo &&
@ -149,6 +163,7 @@ export default class Painter {
borderRadius,
borderWidth,
borderColor,
borderStyle
} = view.css;
if (!borderWidth) {
return;
@ -156,7 +171,7 @@ export default class Painter {
this.ctx.save();
this._preProcess(view, true);
this.ctx.strokeStyle = (borderColor || 'black');
this._doRadius(borderRadius, width, height, borderWidth)
this._border({ borderRadius, width, height, borderWidth, borderStyle })
this.ctx.stroke();
this.ctx.restore();
}
@ -317,7 +332,7 @@ export default class Painter {
this.ctx.rotate(angle);
if (!notClip && view.css && view.css.borderRadius && view.type !== 'rect') {
this._doClip(view.css.borderRadius, width, height);
this._doClip(view.css.borderRadius, width, height, view.css.borderStyle);
}
this._doShadow(view);
if (view.id) {
@ -381,7 +396,7 @@ export default class Painter {
const width = rawWidth + pd[1] + pd[3];
const height = rawHeight + pd[0] + pd[2];
this._doClip(view.css.borderRadius, width, height)
this._doClip(view.css.borderRadius, width, height, view.css.borderStyle)
if (GD.api.isGradient(background)) {
GD.api.doGradient(background, width, height, this.ctx);
} else {
@ -609,8 +624,8 @@ export default class Painter {
} else {
this.ctx.fillStyle = view.css.color;
}
const borderRadius = view.css.borderRadius
this._doRadius(borderRadius, width, height)
const { borderRadius, borderStyle, borderWidth } = view.css
this._border({ borderRadius, width, height, borderWidth, borderStyle })
this.ctx.fill();
this.ctx.restore();
this._doBorder(view, width, height);