diff --git a/lib/pen.js b/lib/pen.js index 58e3303..874b7fa 100644 --- a/lib/pen.js +++ b/lib/pen.js @@ -29,7 +29,7 @@ export default class Painter { const bg = this.data.background; this.ctx.translate(width / 2, height / 2); - this._doBorder(this.data.borderRadius, width, height); + this._doClip(this.data.borderRadius, width, height); if (!bg) { // 如果未设置背景,则默认使用白色 this.ctx.setFillStyle('#fff'); @@ -69,7 +69,10 @@ export default class Painter { } } - _doBorder(borderRadius, width, height) { + /** + * 根据 borderRadius 进行裁减 + */ + _doClip(borderRadius, width, height) { if (borderRadius && width && height) { const r = Math.min(borderRadius.toPx(), width / 2, height / 2); // 防止在某些机型上周边有黑框现象,此处如果直接设置 setFillStyle 为透明,在 Android 机型上会导致被裁减的图片也变为透明, iOS 和 IDE 上不会 @@ -96,7 +99,43 @@ export default class Painter { } } - _preProcess(view) { + /** + * 画边框 + */ + _doBorder(view, width, height) { + const { + borderRadius, + borderWidth, + borderColor, + } = view.css; + if (!borderWidth) { + return; + } + 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.setLineWidth(lineWidth); + this.ctx.setStrokeStyle(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.ctx.stroke(); + this.ctx.restore(); + } + + _preProcess(view, notClip) { let width; let height; let x; @@ -106,7 +145,6 @@ export default class Painter { const fontWeight = view.css.fontWeight === 'bold' ? 'bold' : 'normal'; view.css.fontSize = view.css.fontSize ? view.css.fontSize : '20rpx'; this.ctx.font = `normal ${fontWeight} ${view.css.fontSize.toPx()}px sans-serif`; - this.ctx.setFillStyle(view.css.color ? view.css.color : 'black'); // this.ctx.setFontSize(view.css.fontSize.toPx()); const textLength = this.ctx.measureText(view.text).width; width = view.css.width ? view.css.width.toPx() : textLength; @@ -144,7 +182,9 @@ export default class Painter { break; } this.ctx.rotate(angle); - this._doBorder(view.css.borderRadius, width, height); + if (!notClip) { + this._doClip(view.css.borderRadius, width, height); + } return { width: width, @@ -161,8 +201,9 @@ export default class Painter { width, height, } = this._preProcess(view); - QR.api.draw(view.content, this.ctx, -width / 2, -height / 2, width, height, view.css.background); + QR.api.draw(view.content, this.ctx, -width / 2, -height / 2, width, height, view.css.background, view.css.color); this.ctx.restore(); + this._doBorder(view, width, height); } _drawAbsImage(view) { @@ -176,6 +217,7 @@ export default class Painter { } = this._preProcess(view); this.ctx.drawImage(view.url, -(width / 2), -(height / 2), width, height); this.ctx.restore(); + this._doBorder(view, width, height); } _fillAbsText(view) { @@ -188,6 +230,7 @@ export default class Painter { height, extra, } = this._preProcess(view); + this.ctx.setFillStyle(view.css.color || 'black'); const { lines, lineHeight } = extra; const preLineLength = Math.round(view.text.length / lines); let start = 0; @@ -252,6 +295,7 @@ export default class Painter { } this.ctx.restore(); + this._doBorder(view, width, height); } _drawAbsRect(view) { @@ -263,6 +307,7 @@ export default class Painter { this.ctx.setFillStyle(view.css.color); this.ctx.fillRect(-(width / 2), -(height / 2), width, height); this.ctx.restore(); + this._doBorder(view, width, height); } _getAngle(angle) { diff --git a/lib/qrcode.js b/lib/qrcode.js index b36e22f..264c202 100644 --- a/lib/qrcode.js +++ b/lib/qrcode.js @@ -752,7 +752,7 @@ * 新增$this参数,传入组件的this,兼容在组件中生成 * @param bg 目前只能设置颜色值 */ - draw: function (str, ctx, startX, startY, cavW, cavH, bg, $this, ecc) { + draw: function (str, ctx, startX, startY, cavW, cavH, bg, color, $this, ecc) { var that = this; ecclevel = ecc || ecclevel; if (!ctx) { @@ -763,13 +763,12 @@ str = that.utf16to8(str);//增加中文显示 var frame = that.getFrame(str); - // 组件中生成qrcode需要绑定this var px = size / width; if (bg) { ctx.setFillStyle(bg) ctx.fillRect(startX, startY, cavW, cavW); } - ctx.setFillStyle('#000000'); + ctx.setFillStyle(color || 'black'); for (var i = 0; i < width; i++) { for (var j = 0; j < width; j++) { if (frame[j * width + i]) {