# 验证码
<div class="outWrapper">
<div class="iptWrapper">
<input type="text" placeholder="请输入验证码" name="code" pattern="[A-z]{3}" autocomplete="off" required title="验证码输入框">
</div>
<canvas id="canvas" width="120" height="40" onclick="getValidatorCode('#canvas', 120, 40)"></canvas>
</div>
<div>
<button class="btn">提交</button>
</div>
<input type="number" min="1" max="20" class="iptNumber">
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
css
.outWrapper {
display: flex;
}
#canvas {
cursor: pointer;
}
.iptWrapper {
display: flex;
align-items: center;
justify-content: center;
width: 120;
height: 40px;
border: solid #ccc 1px;
box-sizing: border-box;
padding:4px 8px;
margin-right: 10px;
}
.iptWrapper input {
outline: none;
border: 0;
width: 100%;
height: 38px;
line-height: 38px;
box-sizing: border-box;
}
/* input::after{
content: '已勾选';
width: 100px;
height: 40px;
margin-left: 30px;
display: block;
} */
.btn {
width: 80px;
height: 40px;
background-color: skyblue;
line-height: 40px;
border-color:skyblue;
border:0;
margin-top: 20px;
cursor: pointer;
}
.btn:hover {
color: #fff;
background-color: steelblue;
}
input.iptNumber {
margin-top: 20px;
width: 200px;
height: 40px;
}
input.iptNumber:out-of-range:focus {
background: red;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
js
/**
* @description: 封装的验证码生成函数
* @param {selector} 画布选择器
* @param {width} 画布宽
* @param {height} 画布高
* @return {*}
*/
let compareCode = '';
const oBtn = document.querySelector('.btn');
const oIpt = document.querySelector('.iptWrapper input');
oBtn.onclick = () => {
const iptValue = oIpt.value;
if(!iptValue) return;
if(iptValue.toLowerCase() === compareCode.toLowerCase()) {
alert('验证成功')
} else {
alert('验证失败,请重新输入!');
getValidatorCode('#canvas', 120, 40);
}
// console.log('iptValue', iptValue);
}
function getValidatorCode(selector, width, height) {
let resultCode = '';
// 随机数
function randomNumber(min, max) {
return parseInt(Math.random() * (max-min) + min);
}
//随机颜色
function randomColor (min, max) {
const r = randomNumber(min,max);
const g = randomNumber(min,max);
const b = randomNumber(min,max);
return `rgb(${r},${g},${b})`
}
const canvas = document.querySelector(selector);
const w = width;
const h = height;
const ctx = canvas.getContext('2d'); //创建画笔
// console.log('color', randomColor(180,230));
ctx.fillStyle = randomColor(180,230);
ctx.fillRect(0, 0, w,h);
const pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
for(let i = 0; i<4; i++) {
//随机验证码数字
const c = pool[randomNumber(0, pool.length)];
//随机字体大小
const fs = randomNumber(18,40);
//随机数字旋转角度
const deg = randomNumber(-30, 30);
//字体大小
ctx.font = fs + 'px Simhei';
//基线位置
ctx.textBaseline = 'top';
//设置字体颜色
ctx.fillStyle = randomColor(80,150);
//绘制保存
ctx.save();
//移动每个验证码位置
ctx.translate(30 * i + 15, 15);
//旋转每个字符
ctx.rotate(deg * Math.PI/180);
//填充文字
ctx.fillText(c, -10, -10);
//每次填充完再恢复回去
ctx.restore();
resultCode +=c;
}
//随机生成干扰线
for(var i = 0; i<5; i++) {
//起始路径
ctx.beginPath();
ctx.moveTo(randomNumber(0, w), randomNumber(0, h));
ctx.lineTo(randomNumber(0, w), randomNumber(0, h));
ctx.strokeStyle = randomColor(180, 230);
ctx.closePath();
ctx.stroke();
}
// 随机产生40个小圆点干扰
for(var i = 0; i < 40; i++) {
ctx.beginPath();
//画圆
ctx.arc(randomNumber(0, w),randomNumber(0, h),1, 0, 2 * Math.PI);
ctx.closePath();
//填充颜色
ctx.fillStyle = randomColor(150,200);
ctx.fill(); //填充
}
compareCode = resultCode; //用于和外面验证码比较
return resultCode;
}
getValidatorCode('#canvas', 120, 40);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120