支持边框dashed,可自定义虚线规格
This commit is contained in:
parent
0baa0db6d3
commit
06aaead258
51
lib/pen.js
51
lib/pen.js
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user