React => js+canvas四位數字字母混合驗證碼(數字+大寫字母+小寫字母)
阿新 • • 發佈:2021-01-17
文章目錄
此為最終實現效果!
點選圖片可切換驗證碼
開始進行編寫
html新增canvas標籤
<canvas
onClick={this.reloadPic} //點選切換事件
ref={this.canvas} //ref含義下面講解
width="100"
height="40" //設定高度寬度
></canvas>
ref講解
元件內的標籤都可以定義 ref 屬性來標識自己
1.通過React.createRef()建立Refs並通過ref屬性聯絡到React元件
2.當一個ref通過render放入一個元素中,一個對節點的引用可以通過ref的current屬性得到
頁面初始化生成驗證碼
//頁面初始化後獲取canvas元件,並在canvas元件內生成驗證碼
componentWillMount() {
this.canvas = React.createRef();
}
componentDidMount() {
this.randomCode();
}
### 設定初始值
```javascript
constructor(props) {
super(props);
this.state = {
code: "",
codeLength: 4,//驗證碼長度
contentWidth: 96,
contentHeight: 38 ,//內容高度/寬頻
showError: false,
};
}
設定生死成隨機數函式 randomNum()
//生成一個隨機數
randomNum = (min, max) => {
return Math.floor(Math.random() * (max - min) + min);
};
//生成一個隨機顏色
randomColor(min, max) {
const r = this.randomNum(min, max);
const g = this.randomNum(min, max);
const b = this.randomNum(min, max);
return `rgb(${r}, ${g}, ${b})`;
}
設定干擾線函式drawLine()
具體繪製請看下面 ->繪製路徑(path)
// 繪製干擾線
drawLine(ctx) {
for (let i = 0; i < 1; i++) {
ctx.strokeStyle = this.randomColor(40,180);
//strokeStyle = color 設定圖形輪廓的顏色
ctx.beginPath();
ctx.moveTo(
this.randomNum(0, this.state.contentWidth),
this.randomNum(0, this.state.contentHeight)
);
ctx.lineTo(
this.randomNum(0, this.state.contentWidth),
this.randomNum(0, this.state.contentHeight)
);
ctx.stroke();
}
}
//繪製干擾點
drawDot(ctx) {
for (let i = 0; i < this.state.contentWidth/4; i++) {
ctx.fillStyle = this.randomColor(0, 255);
//fillStyle = color 設定圖形的填充顏色
ctx.beginPath();
ctx.arc(
this.randomNum(0, this.state.contentWidth),
this.randomNum(0, this.state.contentHeight),
1,
0,
2 * Math.PI
);
ctx.fill();
}
}
繪製路徑 (path)
使用路徑繪製圖形需要一些額外的步驟:
1.建立路徑起始點
2.呼叫繪製方法去繪製出路徑
3.把路徑封閉
4.一旦路徑生成,通過描邊或填充路徑區域來渲染圖形。
下面是需要用到的方法:
1.beginPath()
新建一條路徑,路徑一旦建立成功,圖形繪製命令被指向到路徑上生成路徑
2.moveTo(x, y)
把畫筆移動到指定的座標(x, y)。相當於設定路徑的起始點座標。
3.closePath()
閉合路徑之後,圖形繪製命令又重新指向到上下文中
4.stroke()
通過線條來繪製圖形輪廓
5.fill()
通過填充路徑的內容區域生成實心的圖形
設定生成字型顏色和大小及位置 drawText()
drawText(ctx, txt, i) {
//隨機生成字型顏色 呼叫隨機數函式
ctx.fillStyle = this.randomColor(100, 200);
//隨機生成字型大小字號 呼叫隨機數函式
const fontSize = this.randomNum(10, 20);
ctx.font = fontSize + "px SimHei"; //給字號加單位,生成字型
//設定位置
const padding = 10;
//偏移量
const offset = (this.state.contentWidth - 40) (this.state.code.length - 1);
let x = padding;
if (i > 0) {
x = padding + i * offset;
}
//呼叫隨機數函式
let y = this.randomNum(20, this.state.contentHeight - 5);
const deg = this.randomNum(-10, 10);
// 設定座標原點和旋轉角度
ctx.translate(x, y);
ctx.rotate((deg * Math.PI) / 180);
ctx.fillText(txt, 0, 0);
// 恢復座標原點和旋轉角度
ctx.rotate((-deg * Math.PI) / 180);
ctx.translate(-x, -y);
}
生成字母數字組合 randomCode()
//生成字母數字陣列
randomCode() {
let random = "";
const str = "QWERTYUPLKJHGFIODSAZXCVBNMqwlioertyupkjhgfdsazxcvbnm1234567890";
for (let i = 0; i < this.state.codeLength; i++) {
const index = Math.floor(Math.random() * 57);
//取得隨機數的索引(0~57)
random += str[index];
//根據索引取得隨機數加到code上
}
this.setState(
{ code: random,//賦值給code },
() => {
const canvas = this.canvas.current;
//拿到canvas元件 如果不懂請看ref講解
const ctx = canvas.getContext("2d");
//getContext("2d") 物件是內建的 HTML5 物件
//擁有多種繪製路徑、矩形、圓形、字元以及新增影象的方法
ctx.textBaseline = "bottom";
//textBaseline = value 基線對齊選項
//常用值:top, hanging, middle, bottom。
// 繪製背景顏色
ctx.fillStyle = this.randomColor(10, 200 );
//fillStyle = color 設定圖形的填充顏色
ctx.fillRect(0, 0, this.state.contentWidth, this.state.contentHeight);
//fillRect(x, y, width, height):繪製一個填充的矩形。
for (let i = 0; i < this.state.code.length; i++) {
this.drawText(ctx, this.state.code[i], i);
//呼叫生成字型顏色和大小及位置函式
}
this.drawLine(ctx); //呼叫繪製干擾線函式 如同的線條
// this.drawDot(ctx);//呼叫繪製干擾點函式 個人覺得不好看 但是也可以講解一下,後文會在干擾線後面寫
}
);
}
設定點選事件
reloadPic = () => {
this.randomCode();//呼叫生成字母數字組合函式
//同時
this.props.form.setFieldsValue({
sendcode: "", //清空輸入框的驗證碼
});
};
驗證驗證碼是否正確
//驗證驗證碼是否正確
changeCode = (e) => {
//toLowerCase()的意思是把字串所有英文字母轉為小寫
//對驗證碼進行驗證
var code=e.target.value.toLowerCase();
//得到當前輸入的值
var v_code=this.state.code.toLowerCase();
//當前canvas驗證碼的值
//判斷是否相等,不相等則更新
if(code!==''&&code!==v_code){
this.setState({
showError: true,
});
}else{
this.setState({
showError: false,
});
}
}
完成!如有不懂的請在在下方留言