理想是火,点燃熄灭的灯。
之前vue版本的博客里面找了一款图形验证的组件,
由于现在重新开发了react版本的博客
图型验证码 没有找到比较好的组件,
所以干脆看一下之前vue版本的图形验证码的源码
直接搬过来
先看一下效果图:
接下来直接上代码:
组件源码:sidentify.vue
<template> <div class="s-canvas"> <!-- 验证码组件 --> <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas> </div> </template> <script> export default { name: "SIdentify", props: { identifyCode: { type: String, default: "1234" }, fontSizeMin: { type: Number, default: 16 }, fontSizeMax: { type: Number, default: 40 }, backgroundColorMin: { type: Number, default: 180 }, backgroundColorMax: { type: Number, default: 240 }, colorMin: { type: Number, default: 50 }, colorMax: { type: Number, default: 160 }, lineColorMin: { type: Number, default: 40 }, lineColorMax: { type: Number, default: 180 }, dotColorMin: { type: Number, default: 0 }, dotColorMax: { type: Number, default: 255 }, contentWidth: { type: Number, default: 112 }, contentHeight: { type: Number, default: 38 } }, methods: { // 生成一个随机数 randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); }, // 生成一个随机的颜色 randomColor(min, max) { let r = this.randomNum(min, max); let g = this.randomNum(min, max); let b = this.randomNum(min, max); return "rgb(" + r + "," + g + "," + b + ")"; }, drawPic() { let canvas = document.getElementById("s-canvas"); let ctx = canvas.getContext("2d"); ctx.textBaseline = "bottom"; // 绘制背景 ctx.fillStyle = this.randomColor( this.backgroundColorMin, this.backgroundColorMax ); ctx.fillRect(0, 0, this.contentWidth, this.contentHeight); // 绘制文字 for (let i = 0; i < this.identifyCode.length; i++) { this.drawText(ctx, this.identifyCode[i], i); } // this.drawLine(ctx); // this.drawDot(ctx); }, drawText(ctx, txt, i) { ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax); ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + "px SimHei"; let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1)); let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5); var deg = this.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); } // drawLine(ctx) { // // 绘制干扰线 // for (let i = 0; i < 8; i++) { // ctx.strokeStyle = this.randomColor( // this.lineColorMin, // this.lineColorMax // ); // ctx.beginPath(); // ctx.moveTo( // this.randomNum(0, this.contentWidth), // this.randomNum(0, this.contentHeight) // ); // ctx.lineTo( // this.randomNum(0, this.contentWidth), // this.randomNum(0, this.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.contentWidth), // this.randomNum(0, this.contentHeight), // 1, // 0, // 2 * Math.PI // ); // ctx.fill(); // } // } }, watch: { identifyCode() { this.drawPic(); } }, mounted() { this.drawPic(); } }; </script> <style lang="css" scoped> .s-canvas { height: 38px; } canvas { margin-top: 1px; margin-left: 8px; } </style>
引用:
import SIdentify from "./sidentify"; <!--验证码组件--> // template <s-identify :identifyCode="123456789"></s-identify> // v-data identifyCodes: "1234567890", identifyCode: "", // v-methods randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); }, refreshCode() { this.identifyCode = ""; this.makeCode(this.identifyCodes, 4); }, makeCode(o, l) { for (let i = 0; i < l; i++) { this.identifyCode += this.identifyCodes[ this.randomNum(0, this.identifyCodes.length) ]; } }, // v-created created() { this.refreshCode(); },
import React, { Component } from "react"; let defaultDataObj = { identifyCodes: { type: String, default: "1234567890", }, identifyCode: { type: String, default: "1234", }, fontSizeMin: { type: Number, default: 16, }, fontSizeMax: { type: Number, default: 40, }, backgroundColorMin: { type: Number, default: 180, }, backgroundColorMax: { type: Number, default: 240, }, colorMin: { type: Number, default: 50, }, colorMax: { type: Number, default: 160, }, lineColorMin: { type: Number, default: 40, }, lineColorMax: { type: Number, default: 180, }, dotColorMin: { type: Number, default: 0, }, dotColorMax: { type: Number, default: 255, }, contentWidth: { type: Number, default: 112, }, contentHeight: { type: Number, default: 38, }, }; class SIdentify extends Component { constructor(props) { super(props); this.state = {}; } // 生成一个随机数 randomNum = (min, max) => { return Math.floor(Math.random() * (max - min) + min); }; // 生成一个随机的颜色 randomColor = (min, max) => { let r = this.randomNum(min, max); let g = this.randomNum(min, max); let b = this.randomNum(min, max); return "rgb(" + r + "," + g + "," + b + ")"; }; drawPic = () => { let canvas = document.getElementById("s-canvas"); let ctx = canvas.getContext("2d"); console.log(canvas); console.log(ctx); ctx.textBaseline = "bottom"; // 绘制背景 console.log(defaultDataObj.backgroundColorMin); ctx.fillStyle = this.randomColor( defaultDataObj.backgroundColorMin.default, defaultDataObj.backgroundColorMax.default ); ctx.fillRect( 0, 0, defaultDataObj.contentWidth.default, defaultDataObj.contentHeight.default ); // 绘制文字 for (let i = 0; i < defaultDataObj.identifyCode.default.length; i++) { this.drawText(ctx, defaultDataObj.identifyCode.default[i], i); } this.drawLine(ctx); this.drawDot(ctx); }; drawText = (ctx, txt, i) => { ctx.fillStyle = this.randomColor( defaultDataObj.colorMin.default, defaultDataObj.colorMax.default ); ctx.font = this.randomNum( defaultDataObj.fontSizeMin.default, defaultDataObj.fontSizeMax.default ) + "px SimHei"; let x = (i + 1) * (defaultDataObj.contentWidth.default / (defaultDataObj.identifyCode.default.length + 1)); let y = this.randomNum( defaultDataObj.fontSizeMax.default, defaultDataObj.contentHeight.default - 5 ); var deg = this.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); }; drawLine = (ctx) => { // 绘制干扰线 for (let i = 0; i < 8; i++) { ctx.strokeStyle = this.randomColor( defaultDataObj.lineColorMin.default, defaultDataObj.lineColorMax.default ); ctx.beginPath(); ctx.moveTo( this.randomNum(0, defaultDataObj.contentWidth.default), this.randomNum(0, defaultDataObj.contentHeight.default) ); ctx.lineTo( this.randomNum(0, defaultDataObj.contentWidth.default), this.randomNum(0, defaultDataObj.contentHeight.default) ); 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.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI ); ctx.fill(); } } changeCode = () => { this.refreshCode(); }; makeCode = (o, l) => { for (let i = 0; i < l; i++) { defaultDataObj.identifyCode.default += defaultDataObj.identifyCodes.default[ this.randomNum(0, defaultDataObj.identifyCodes.default.length) ]; } console.log("校验", defaultDataObj.identifyCode.default); this.drawPic(); }; refreshCode = () => { defaultDataObj.identifyCode.default = ""; this.makeCode(defaultDataObj.identifyCodes.default, 4); }; render() { return ( <div> 验证码: <canvas id="s-canvas" width="112px" height="38"></canvas> <button onClick={this.changeCode}>切换验证码</button> </div> ); } componentDidMount() { this.refreshCode(); } } export default SIdentify;
逻辑都一样就是写法改了一下,
有问题可以留言
作者: Bill 本文地址: http://biaoblog.cn/info?id=1643365247270
版权声明: 本文为原创文章,版权归 biaoblog 个人博客 所有,欢迎分享本文,转载请保留出处,谢谢!
上一篇:原生的文件拖拽上传