之前vue版本的博客里面找了一款图形验证的组件,
由于现在重新开发了react版本的博客
图型验证码 没有找到比较好的组件,
所以干脆看一下之前vue版本的图形验证码的源码
直接搬过来
先看一下效果图:
接下来直接上代码:
VUE版本:
组件源码:sidentify.vue
代码语言:javascript复制<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>
引用:
代码语言:javascript复制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();
},
下面是react版本:
代码语言:javascript复制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;
逻辑都一样就是写法改了一下,
有问题可以留言