export class VertifyCode { id: string; height: number; width: number; canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D | undefined; pool: string; code: string; constructor(options: VertifyCodeOptionsType) { const { id = 'vertify-wrap', canvas } = options; this.id = id; this.width = canvas.width; this.height = canvas.height; this.canvas = canvas; this.pool = 'ABCDEFGHIJKLIMNOPQRSTUVWSYZ1234567890'; this.code = ''; this.init(); } createCanvas() { this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D; this.ctx.fillStyle = this.rc(180, 230); this.ctx.fillRect(0, 0, this.width, this.height); } //1.新建一个函数产生随机数 rn(min: any, max: number) { return parseInt(Math.random() * (max - min) + min); } //2.新建一个函数产生随机颜色 rc(min: number, max: number) { let r = this.rn(min, max); let g = this.rn(min, max); let b = this.rn(min, max); return `rgb(${r},${g},${b})`; } init() { this.createCanvas(); this.render(); } render() { this.code = ''; const { pool, ctx, rn, width: w, height: h } = this; if (!ctx) return; ctx.fillRect(0, 0, this.width, this.height); for (let i = 0; i < 4; i++) { let c = pool[rn(0, pool.length)]; //随机的字 this.code += c; let fs = rn(18, 40); //字体的大小 let deg = rn(-30, 30); //字体的旋转角度 ctx.font = fs + 'px Simhei'; ctx.textBaseline = 'top'; ctx.fillStyle = this.rc(80, 150); ctx.save(); ctx.translate(30 * i + 15, 15); ctx.rotate((deg * Math.PI) / 180); ctx.fillText(c, -15 + 5, -15); ctx.restore(); } //5.随机产生5条干扰线,干扰线的颜色要浅一点 for (let i = 0; i < 5; i++) { ctx.beginPath(); ctx.moveTo(rn(0, w), rn(0, h)); ctx.lineTo(rn(0, w), rn(0, h)); ctx.strokeStyle = this.rc(180, 230); ctx.closePath(); ctx.stroke(); } //6.随机产生40个干扰的小点 for (let i = 0; i < 40; i++) { ctx.beginPath(); ctx.arc(rn(0, w), rn(0, h), 1, 0, 2 * Math.PI); ctx.closePath(); ctx.fillStyle = this.rc(150, 200); ctx.fill(); } } }
使用:
export default function NewLogin() { const vertifyRef = useRef<VertifyCode>(); const [form] = Form.useForm(); useEffect(() => { const click = () => { vertifyRef.current?.render(); }; let dom = document.getElementsByClassName('vertify-wrap')[0] as HTMLCanvasElement; vertifyRef.current = new VertifyCode({ canvas: dom }); dom.addEventListener('click', click); return () => { dom.removeEventListener('click', click); }; }, []); const onFinish = async (value: any) => { const { username, password, code } = value; if(code== vertifyRef.current?.code){ }else{ message.warning('验证码输入错误,请重新验证') vertifyRef.current?.render(); } }; return ( <div className="NewLogin"> <div className="n-login-content"> <div className="title">吴中商务云管理信息系统</div> <div className="login-con"> <Form form={form} name="horizontal_login" size="large" onFinish={onFinish} className="login-form"> <Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}> <Input prefix={<UserOutlined className="site-form-item-icon" style={{ color: '#9CA5B6' }} />} placeholder="请输入用户名" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}> <Input prefix={<LockOutlined className="site-form-item-icon" style={{ color: '#9CA5B6' }} />} type="password" placeholder="请输入密码" /> </Form.Item> <Row> <Col> <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}> <Input prefix={<VertifyImg />} type="password" placeholder="请输入验证码" /> </Form.Item> </Col> <Col> <canvas className="vertify-wrap" style={{ marginLeft: '15px', cursor: 'pointer' }} width="150" height="40"></canvas> </Col> </Row> <Form.Item shouldUpdate> {() => ( <Button type="primary" htmlType="submit" style={{ backgroundColor: '#0080EF', borderColor: '#0080EF', minWidth: 148, width: '100%', borderRadius: '6px', }}> 登录 </Button> )} </Form.Item> </Form> <div style={{ marginTop: 10 }}> <Checkbox style={{ color: '#666' }}>记住密码</Checkbox> </div> </div> </div> </div> ); }
发表评论
侧栏公告
寄语
譬如朝露博客是一个分享前端知识的网站,联系方式11523518。
热评文章
标签列表
热门文章
友情链接