React/Umi 生成随机验证码

简介: React/Umi 生成随机验证码

Login.tsx

import PicAuthCode from './PicAuthCode';
import React, { useState } from 'react';
const Login: React.FC = () => {
 const [Verification,setVerificationCode] = useState('11111')
  // 生成验证码 
  const setCode = () => {
     const words = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
     let code = ''
     for (let i = 0; i < 4; i++) {
       code += words[Math.floor(Math.random() * 52)]
     }
     setVerificationCode(code)
     return code
  }
   return (
        <div>
          {Verification}
            <PicAuthCode setCode={setCode} />
        </div>
    )
}
export default  Login

PicAuthCode.jsx

import { useState, useEffect, useRef } from 'react'
export default function PicAuthCode(props) {
    PicAuthCode.defaultProps = {
        setCode: () => ""    // 更新验证码的方法,返回验证码即可
    }
    const [config] = useState({
        contentWidth: 100,
        contentHeight: 35,
        backgroundColorMin: 180,
        backgroundColorMax: 240,
        fontSizeMin: 25,
        fontSizeMax: 30,
        colorMin: 50,
        colorMax: 160,
        lineColorMin: 40,
        lineColorMax: 180,
        dotColorMin: 0,
        dotColorMax: 255,
        textStyle: { fontSize: '12px', color: 'gray', marginLeft: '6px', cursor: 'pointer', padding: '5px', userSelect: "none" }
    })
    const [identifyCode, setIdentifyCode] = useState('')
    const canvasRef = useRef()
    useEffect(() => {
        refresh()
    }, [])
    useEffect(() => {
        identifyCode && drawPic()
    })
    PicAuthCode.defaultProps = {
        setCode: () => ""      // 更新验证码的函数
    }
    const drawPic = () => {
        let canvas = canvasRef.current
        let ctx = canvas.getContext('2d')
        ctx.fillStyle = randomColor(config.backgroundColorMin, config.backgroundColorMax)
        ctx.strokeStyle = randomColor(config.backgroundColorMin, config.backgroundColorMax)
        ctx.fillRect(0, 0, config.contentWidth, config.contentHeight)
        ctx.strokeRect(0, 0, config.contentWidth, config.contentHeight)
        for (let i = 0; i < identifyCode.length; i++) {
            drawText(ctx, identifyCode[i], i)
        }
        drawLine(ctx)
        drawDot(ctx)
    }
    const randomNum = (min, max) => {
        return Math.floor(Math.random() * (max - min) + min)
    }
    const randomColor = (min, max) => {
        let r = randomNum(min, max)
        let g = randomNum(min, max)
        let b = randomNum(min, max)
        return 'rgb(' + r + ',' + g + ',' + b + ')'
    }
    const drawText = (ctx, txt, i) => {
        ctx.fillStyle = randomColor(config.colorMin, config.colorMax)
        ctx.font = randomNum(config.fontSizeMin, config.fontSizeMax) + 'px SimHei'
        ctx.textBaseline = 'alphabetic'
        let x = (i + 1) * (config.contentWidth / (identifyCode.length + 1))
        let y = randomNum(config.fontSizeMax, config.contentHeight - 12)
        let deg = randomNum(-45, 45)
        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)
    }
    const drawLine = (ctx) => {
        for (let i = 0; i < 8; i++) {
            ctx.strokeStyle = randomColor(config.lineColorMin, config.lineColorMax)
            ctx.beginPath()
            ctx.moveTo(randomNum(0, config.contentWidth), randomNum(0, config.contentHeight)) //设置起点x,y
            ctx.lineTo(randomNum(0, config.contentWidth), randomNum(0, config.contentHeight)) //绘制直线 x,y 一条当前位置到x,y点的直线
            ctx.stroke()
        }
    }
    const drawDot = (ctx) => {
        for (let i = 0; i < 100; i++) {
            ctx.fillStyle = randomColor(0, 255)
            ctx.beginPath()
            ctx.arc(randomNum(0, config.contentWidth), randomNum(0, config.contentHeight), 1, 0, 2 * Math.PI)
            ctx.fill()
        }
    }
    const refresh = () => {
        const words = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
        let code = ''
        for (let i = 0; i < 4; i++) {
            code += words[Math.floor(Math.random() * 52)]
        }
        props.setCode ? setIdentifyCode(props.setCode()) : setIdentifyCode(code)
    }
    return (
        <div style={{ margin: '3px 0px 12px 4px' }}>
            <canvas
                ref={canvasRef}
                width={config.contentWidth}
                height={config.contentHeight}
                onClick={refresh}
            />
        </div>
    )
}
相关文章
|
7月前
|
开发框架 自然语言处理 前端开发
【第25期】一文读懂React企业级前端应用框架Umi
【第25期】一文读懂React企业级前端应用框架Umi
379 0
|
7月前
|
前端开发 JavaScript 架构师
react+typescript+umi+dva+antd
react+typescript+umi+dva+antd
113 0
|
7月前
|
资源调度 前端开发 定位技术
React umi地图的展示
React umi地图的展示
|
7月前
|
前端开发
React umi框架局部请求拦截器
React umi框架局部请求拦截器
115 0
|
前端开发 JavaScript
微前端使用qiankun实现,react主应用同时兼顾react,vue3,umi子应用
微前端使用qiankun实现,react主应用同时兼顾react,vue3,umi子应用
722 0
|
前端开发
React/Umi中实现移动端滑动图片验证功能
React/Umi中实现移动端滑动图片验证功能
251 0
react+umi+dva+ts基础基础使用
react+umi+dva+ts基础基础使用
|
7月前
|
设计模式 前端开发 数据可视化
【第4期】一文了解React UI 组件库
【第4期】一文了解React UI 组件库
382 0
|
7月前
|
存储 前端开发 JavaScript
【第34期】一文学会React组件传值
【第34期】一文学会React组件传值
80 0
|
7月前
|
资源调度 前端开发 JavaScript
React 的antd-mobile 组件库,嵌套路由
React 的antd-mobile 组件库,嵌套路由
132 0