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