在React中隨機生成圖形驗證碼


各個方法

在輸入框中定義一個位置存放圖形

完整代碼 方便復制粘貼

import React, { Component } from 'react';
import styles from './leftLogin.scss';
import { withRouter } from 'dva/router';
import { connect } from 'dva';
import { Form, Icon, Input, Button, Checkbox } from 'antd';

@connect(({ login }) => ({
login,
}))

class leftLogin extends Component {
constructor(props) {
super(props);
this.state = {
code: '',
codeLength: 4,
fontSizeMin: 20,
fontSizeMax: 22,
backgroundColorMin: 240,
backgroundColorMax: 250,
colorMin: 10,
colorMax: 20,
lineColorMin: 40,
lineColorMax: 180,
contentWidth: 96,
contentHeight: 38,
showError: false, // 默認不顯示驗證碼的錯誤信息
};
}

UNSAFE_componentWillMount() {
this.canvas = React.createRef();
}

componentDidMount() {
this.drawPic();
}

// 點擊登錄按鈕
handleSubmit = e => {
e.preventDefault();
this.drawPic();
this.props.form.validateFields((err, values) => {
if (!err && this.state.showError !== true) {
// 調登錄接口
const { dispatch } = this.props;
dispatch({
type: 'login/login',
payload: {
account: values.username,
pwd: values.password
}
})
this.props.form.setFieldsValue({
sendcode: '',
});
this.setState({
showError: false
})
}
});
}

// 跳轉到忘記密碼頁
forget = () => {
this.props.history.push('/forget')
}

// 跳轉到注冊頁
regist = () => {
this.props.history.push('/regist')
}

// 生成一個隨機數
randomNum = (min, max) => {
return Math.floor(Math.random() * (max - min) + min)
}

drawPic = () => {
this.randomCode()
}

// 生成一個隨機的顏色
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})
}

drawText(ctx, txt, i) {
ctx.fillStyle = this.randomColor(this.state.colorMin, this.state.colorMax)
let fontSize = this.randomNum(this.state.fontSizeMin, this.state.fontSizeMax)
ctx.font = fontSize + 'px SimHei'
let padding = 10;
let offset = (this.state.contentWidth - 40) / (this.state.code.length - 1)
let x = padding;
if (i > 0) {
x = padding + (i * offset)
}
let y = this.randomNum(this.state.fontSizeMax, this.state.contentHeight - 5)
if (fontSize > 40) {
y = 40
}
let 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)
}

drawLine(ctx) {
// 繪制干擾線
for (let i = 0; i < 1; i++) {
ctx.strokeStyle = this.randomColor(this.state.lineColorMin, this.state.lineColorMax)
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 < 100; i++) {
ctx.fillStyle = this.randomColor(0, 255)
ctx.beginPath()
ctx.arc(this.randomNum(0, this.state.contentWidth), this.randomNum(0, this.state.contentHeight), 1, 0, 2 * Math.PI)
ctx.fill()
}
}

reloadPic = () => {
this.drawPic()
this.props.form.setFieldsValue({
sendcode: '',
});
}

// 輸入驗證碼
changeCode = e => {

if (e.target.value.toLowerCase() !== '' && e.target.value.toLowerCase() !== this.state.code.toLowerCase()) {
  this.setState({
    showError: true
  })
} else if (e.target.value.toLowerCase() === '') {
  this.setState({
    showError: false
  })
} else if (e.target.value.toLowerCase() === this.state.code.toLowerCase()) {
  this.setState({
    showError: false
  })
}

}

// 隨機生成驗證碼
randomCode() {
let random = ''
// 去掉了I l i o O
const str = 'QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890'
for (let i = 0; i < this.state.codeLength; i++) {
let index = Math.floor(Math.random() * 57);
random += str[index];
}
this.setState({
code: random
},()=>{
let canvas = this.canvas.current;
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 繪制背景
ctx.fillStyle = this.randomColor(this.state.backgroundColorMin, this.state.backgroundColorMax)
ctx.fillRect(0, 0, this.state.contentWidth, this.state.contentHeight)
// 繪制文字
for (let i = 0; i < this.state.code.length; i++) {
this.drawText(ctx, this.state.code[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
})
}

render() {
const { getFieldDecorator } = this.props.form;
const suffix =





return (

<Form onSubmit={this.handleSubmit} style={{ width: '398px', margin: '0 auto', fontSize: '12px' }}>
<Form.Item>
{getFieldDecorator('username', {
rules: [{ required: true, message: '請輸入用戶名!' }, {
pattern: /^1[3456789]\d{9}$/,
message: '手機號格式不正確'
}],
})(
<Input
size="large"
prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
placeholder="請輸入手機號"
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [{ required: true, message: '請輸入密碼!' }, {
pattern: /^.{6,}$/,
message: '密碼格式不正確(不得低於6位)'
}],
})(
<Input
size="large"
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
type="password"
placeholder="請輸入密碼"
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('sendcode', {
rules: [{ required: true, message: '請輸入校驗碼!' },],
})(
<Input
size="large"
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
suffix={suffix}
onChange={this.changeCode}
placeholder="請輸入校驗碼"
/>,
)}
{
this.state.showError ?

請輸入正確的驗證碼

: null
}
</Form.Item>

          <Form.Item className={this.state.showError ? styles.inputBottom : ''}>
            {getFieldDecorator('remember', {
              valuePropName: 'checked',
              initialValue: true,
            })(<Checkbox>7天內免登錄</Checkbox>)}
            <a className={styles.forget} onClick={this.forget}>
              忘記密碼
            </a>
            <Button
              size="large"
              type="primary"
              htmlType="submit"
              className={styles.button}
            >
              登錄
            </Button>
            <a onClick={this.regist}>新用戶注冊</a>
          </Form.Item>
        </Form>
  </div>
);

}
}

const WrappedNormalLoginForm = Form.create({ name: 'normal_login' })(leftLogin);

export default withRouter(WrappedNormalLoginForm);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM