微信小程序添加图片验证码
生成验证码代码来源:https://blog.csdn.net/java558/article/details/118105910,我把业务代码抽出来弄成一个组件。自己调试过程中遇到了一点问题。
实现
<!-- components/captcha/captcha.wxml -->
<view class="captcha-box ">
<canvas class="captcha verify-class" type="2d" id="captchaCanvas" bind:tap="changeCode"/>
</view>
// components/captcha/captcha.js
Component({
/**
* 页面的初始数据
*/
data: {
verificationCode: "",
text: ""
},
ready: function() {
const that = this;
that.refreshCode()
},
methods: {
// 点击改变验证码
changeCode: function () {
this.refreshCode();
},
randomNum: function (min, max) {
return Math.floor(Math.random() * (max - min) + min);
},
// 生成一个随机色
randomColor: function (min, max) {
let r = this.randomNum(min, max);
let g = this.randomNum(min, max);
let b = this.randomNum(min, max);
return `rgb(${r}, ${g}, ${b})`;
},
// 重新绘制图片验证码
refreshCode: function () {
wx.createSelectorQuery().in(this)
.select('#captchaCanvas') // 在 WXML 中填入的 id
.fields({
node: true,
size: true
})
.exec((res) => {
// Canvas 对象
const canvas = res[0].node
// 渲染上下文
const ctx = canvas.getContext('2d')
// Canvas 画布的实际绘制宽高
const width = res[0].width
const height = res[0].height
// 初始化画布大小
const dpr = wx.getWindowInfo().pixelRatio;
canvas.width = width * dpr
canvas.height = height * dpr
ctx.scale(dpr, dpr);
// 填充一个矩形
ctx.fillStyle = this.randomColor(180, 240); //颜色若太深可能导致看不清
ctx.fillRect(0, 0, 90, 28)
/**绘制文字**/
var arr;
var text = '';
var str = 'ABCEFGHJKLMNPQRSTWXY123456789';
for (var i = 0; i < 4; i++) {
var txt = str[this.randomNum(0, str.length)];
ctx.fillStyle = this.randomColor(50, 160); //随机生成字体颜色
ctx.font = this.randomNum(20, 26) + 'px SimHei'; //随机生成字体大小
var x = 5 + i * 20;
var y = this.randomNum(20, 25);
var deg = this.randomNum(-20, 20);
//修改坐标原点和旋转角度
ctx.translate(x, y);
ctx.rotate(deg * Math.PI / 180);
ctx.fillText(txt, 5, 0);
text = text + txt;
//恢复坐标原点和旋转角度
ctx.rotate(-deg * Math.PI / 180);
ctx.translate(-x, -y);
}
/**绘制干扰线**/
for (var i = 0; i < 4; i++) {
ctx.strokeStyle = this.randomColor(40, 180);
ctx.beginPath();
ctx.moveTo(this.randomNum(0, 90), this.randomNum(0, 28));
ctx.lineTo(this.randomNum(0, 90), this.randomNum(0, 28));
ctx.stroke();
}
/**绘制干扰点**/
for (var i = 0; i < 20; i++) {
ctx.fillStyle = this.randomColor(0, 255);
ctx.beginPath();
ctx.arc(this.randomNum(0, 90), this.randomNum(0, 28), 1, 0, 2 * Math.PI);
ctx.fill();
}
// ctx.draw(false, function() {
this.setData({
text: text
})
console.log("text", text);
this.triggerEvent("imgVerify", text);
// });
})
},
},
})
有一点小问题,就是红框的位置实际才是canvas
的大小,
问题
wx.createSelectorQuery()
后面要加in(this)
,不然会报下面的错
- 在组件的生命周期,初始化
canvas
要写在ready
,不然也会报问题1那个错
- 做的时候
canvas
出现了,但是没有绘制到图片验证码。我是把它写在页面底部,但是拉一下滚动条又出现了。不知道是什么问题。用wx:if
设置显示隐藏后,就正常了。