在React中随机生成图形验证码

时间:2021-05-23 21:26:28

在React中随机生成图形验证码

在React中随机生成图形验证码

各个方法

在React中随机生成图形验证码

在React中随机生成图形验证码

在React中随机生成图形验证码

在React中随机生成图形验证码

在React中随机生成图形验证码

在React中随机生成图形验证码

在输入框中定义一个位置存放图形

在React中随机生成图形验证码

在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,

fontSi*: 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.fontSi*, 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);