zoukankan      html  css  js  c++  java
  • 在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={{ '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);

  • 相关阅读:
    控制视图函数 接受 post or get 的访问方法的 写法
    带进度条的重定向
    装饰器@property,让调用类里面的函数 和 调用类里面的变量一样写法。 含 类中@property与@xxx.setter的方法介绍。
    filter() 函数 判断数组里面的 数据 是否符合 要求,符合就加入数组
    套件的使用追加
    linux下几个常用软件
    PHP探针
    Yii2 用户登录
    Datatables JQuery插件
    收藏的几个经典Flash
  • 原文地址:https://www.cnblogs.com/zppsakura/p/11375864.html
Copyright © 2011-2022 走看看