手写一个校验码和验证框
- 手写一个校验码和校验框
<template>
<div>
<canvas ref="captchaCanvas" :width="canvasWidth" :height="canvasHeight" @click="refreshCaptcha"></canvas>
<input type="text" v-model="inputValue" @keyup.enter="checkCaptcha">
</div>
</template>
<script>
export default {
props: {
captchaLength: {
type: Number,
default: 4 // 默认验证码长度为4
},
canvasWidth: {
type: Number,
default: 100 // 默认画布宽度为100
},
canvasHeight: {
type: Number,
default: 40 // 默认画布高度为40
},
font: {
type: String,
default: '20px Arial' // 默认字体样式
},
textColor: {
type: String,
default: '#000' // 默认文本颜色为黑色
},
bgColor: {
type: String,
default: '#fff' // 默认背景颜色为白色
},
lineColor: {
type: String,
default: '#000' // 默认干扰线颜色为黑色
},
lineWidth: {
type: Number,
default: 1 // 默认干扰线宽度为1
}
},
data() {
return {
captchaText: '', // 图形验证码的文本
inputValue: '', // 用户输入的值
isInputEntered: false // 用户是否输入完成标志
};
},
mounted() {
this.generateCaptcha();
},
watch: {
inputValue(value) {
if (value === this.captchaText && this.isInputEntered) {
this.checkCaptcha();
}
}
},
methods: {
// 生成图形验证码
generateCaptcha() {
const canvas = this.$refs.captchaCanvas;
const ctx = canvas.getContext('2d');
// 生成随机验证码文本
this.captchaText = this.generateRandomString(this.captchaLength);
// 绘制验证码背景
ctx.fillStyle = this.bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制干扰线
for (let i = 0; i < 5; i++) {
this.drawRandomLine(ctx);
}
// 绘制验证码文本
for (let i = 0; i < this.captchaText.length; i++) {
const char = this.captchaText.charAt(i);
const x = (i + 1) * (canvas.width / (this.captchaLength + 1));
const y = canvas.height / 2;
this.drawText(ctx, char, x, y);
}
},
// 绘制随机干扰线
drawRandomLine(ctx) {
const canvas = this.$refs.captchaCanvas;
const x1 = Math.random() * canvas.width;
const y1 = Math.random() * canvas.height;
const x2 = Math.random() * canvas.width;
const y2 = Math.random() * canvas.height;
const color = this.generateRandomColor(); // 随机颜色
ctx.strokeStyle = color;
ctx.lineWidth = this.lineWidth;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
},
// 绘制验证码文本
drawText(ctx, char, x, y) {
const color = this.generateRandomColor(); // 随机颜色
const rotation = Math.random() * 30 - 15; // 随机旋转角度,范围为 -15 到 15 度
ctx.font = this.font;
ctx.fillStyle = color;
ctx.save();
ctx.translate(x, y);
ctx.rotate(rotation * Math.PI / 180); // 将角度转换为弧度
ctx.fillText(char, 0, 0);
ctx.restore();
},
// 刷新验证码
refreshCaptcha() {
this.generateCaptcha();
},
// 校验验证码
checkCaptcha() {
if (this.inputValue.toLowerCase() === this.captchaText.toLowerCase()) {
alert('验证码正确!');
} else {
alert('验证码错误!');
this.inputValue = ''; // 清空输入框
this.generateCaptcha(); // 重新生成验证码
}
},
// 生成指定长度的随机字符串
generateRandomString(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
},
// 生成随机颜色
generateRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16); // 生成随机的十六进制颜色值
}
}
};
</script>

先这样吧
后面补

浙公网安备 33010602011771号