前言
在我们编写登陆、注册页面的时候为了防止批量注册和登陆,此时就需要验证码来对前端登陆注册的接口进行保护。接下来我们使用canvas制作一个简单的登陆注册的验证码。
实现思路
- 创建canvas画布并设置画布尺寸
- 设置随机生成的画布背景颜色
- 绘制画布干扰点
- 随机生成4个合法字符绘制到画布上
准备工作
需要准备一些颜色或者写一个随机生成一些颜色的方法。
// 颜色表
const backgroundColor: string[] = [
'#A98175',
'#F9906F',
'#F3D3E7',
'#FCEFE8',
'#FFFFFF',
'#F9906F',
'#FFB3A7',
'#BCE672',
'#88ADA6',
'#C0EBD7',
'#E0EEE8',
'#E3F9FD',
'#A1AFC9'
];
// 生成一个随机颜色
function randomColor(x: number, y: number) {
const r = randomNum(x, y);
const g = randomNum(x, y);
const b = randomNum(x, y);
return `rgb(${r},${g},${b})`;
}
封装一个生成随机数的方法
/** 生成一个随机数 */
const randomNum = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min) + min);
};
随机生成一个合法字符方法,比如“0”和“o”那些比较难区分的字符排除掉
function randomCharacter(): string {
// 大小写a-z,0-9的正则表达式
const regexp = new RegExp(/^[a-zA-Z\d]+$/)
const random = randomNum(1, 122);
const randomString = String.fromCharCode(random);
const isTrue = randomString.search( regexp);
const disableCharacter: string[] = ['l', 'I', 'o', 'O', '0', '1'];
if (disableCharacter.includes(randomString)) {
return randomCharacter();
}
if (isTrue === -1) {
return randomCharacter();
}
return randomString;
}
实现代码
先创建一个canvas标签并使用width,height属性设置画布的尺寸,
<canvas id="canvasScreen" width="150" height="40"></canvas>
使用id获取元素,并用getContext() 方法,该对象提供了用于在画布上绘图的方法和属性。 同时设置画板的背景颜色
function initCode() {
const canvasScreen = document.getElementById('canvasScreen');
const ctx = (canvasScreen as any).getContext('2d');
// 随机获取颜色
ctx.fillStyle = backgroundColor[Math.floor(Math.random() * 13)];
// 绘制被填充的背景
ctx.fillRect(0, 0, 150, 40);
// 绘制背景的位置
ctx.textBaseline = 'bottom';
// 调用绘制方法
randerCanvas();
}
绘制随机生成字符的方法
// 绘制文字方法
function drawText(print: string, i: number) {
// 随机生成字体颜色
ctx.fillStyle = randomColor(1, 125);
// 随机设置字体大小
ctx.font = `${randomNum(30, 40)}px SimHei`;
// 字体偏移量
const x = 30 * i;
const y = 35;
const deg = randomNum(-25, 25);
// 修改坐标原点和旋转角度
ctx.translate(x, y);
ctx.rotate((deg * Math.PI) / 180);
ctx.fillText(print, 0, 0);
// 恢复坐标原点和旋转角度
ctx.rotate((-deg * Math.PI) / 180);
ctx.translate(-x, -y);
}
在画布上绘制若干个干扰点
function drawDot() {
for (let i = 0; i < 20; i += 1) {
ctx.fillStyle = randomColor(1, 255);
ctx.beginPath();
ctx.arc(randomNum(0, 180), randomNum(0, 60), 1, 0, 2 * Math.PI);
ctx.fill();
}
}
最后调用之前写的方法渲染画布内容,在初始化时可以调用。
function randerCanvas() {
// 随机生成四个字符
for (let i = 1; i < 5; i += 1) {
const newText = randomCharacter();
drawText(newText, i);
}
// 调用绘制干扰点方法
drawDot();
}
最后因为我使用的时vue3.2 setup语法糖,此时元素还没有被渲染,直接初始化会id获取不到当前元素报错,所以必须将方法放在onMounted()中。
onMounted(() => {
initCode();
});
总结
这些就是实现登陆,注册验证验证码的实现方法。在实际开发中,一般情况下四位数的验证码是由后端返回的,只需要通过异步回调方法中重新调用绘制方法即可。