支持边框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,
|
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);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user