Created
April 1, 2019 09:48
-
-
Save mcattx/2e1c0794855e2787d16e30e11b04bbab to your computer and use it in GitHub Desktop.
纯前端图形验证码
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Verify { | |
constructor(options = {}) { | |
this.defaultConfig = { | |
id: '', | |
canvasId: 'verifyCanvas', | |
width: '100', | |
height: '30', | |
// 默认 blend - 数字字母混合类型, number - 纯数字, letter 纯字母 | |
type: 'blend', | |
code: '' | |
} | |
this.config = Object.assign({}, this.defaultConfig, options) | |
this.config.version = '0.1.0' | |
this.config.numberRange = '0,1,2,3,4,5,6,7,8,9'.split(',') | |
this.config.letterRange = this._getAllLetter() | |
this.init() | |
this.refresh() | |
} | |
getVersion() { | |
return this.config.version | |
} | |
init() { | |
const dom = document.getElementById(this.config.id) | |
const canvas = document.createElement('canvas') | |
canvas.id = this.config.canvasId | |
canvas.width = this.config.width | |
canvas.height = this.config.height | |
canvas.style.cursor = 'pointer' | |
canvas.innerHTML = '您的浏览器版本不支持 canvas' | |
dom.appendChild(canvas) | |
canvas.onclick = () => { | |
this.refresh() | |
} | |
} | |
refresh() { | |
this.config.code = '' | |
const canvas = document.getElementById(this.config.canvasId) | |
const ctx = canvas.getContext('2d') | |
ctx.textBaseline = 'middle' | |
ctx.fillStyle = this._randomColor(180, 240) | |
ctx.fillRect(0, 0, this.config.width, this.config.height) | |
var textRange = '' | |
if (this.config.type === 'blend') { | |
textRange = this.config.numberRange.concat(this.config.letterRange) | |
} else if (this.config.type === 'number') { | |
textRange = this.config.numberRange | |
} else { | |
textRange = this.config.letterRange | |
} | |
for (let i = 0; i < 4; i++) { | |
const text = textRange[this._randomNumber(0, textRange.length)] | |
this.config.code += text | |
ctx.font = '24px SimHei' | |
ctx.fillStyle = this._randomColor(50, 160) | |
ctx.shadowOffsetX = this._randomNumber(-3, 3) | |
ctx.shadowOffsetY = this._randomNumber(-3, 3) | |
ctx.shadowBlur = this._randomNumber(-3, 3) | |
ctx.shadowColor = 'rgba(0, 0, 0, 0.3)' | |
const x = this.config.width / 5 * i | |
const y = this.config.height / 2 | |
const deg = this._randomNumber(-30, 30) | |
// 设置旋转角度和坐标原点 | |
ctx.translate(x, y) | |
ctx.rotate(deg * Math.PI / 180) | |
ctx.fillText(text, 0, 0) | |
// 恢复旋转角度和坐标原点 | |
ctx.rotate(-deg * Math.PI / 180) | |
ctx.translate(-x, -y) | |
} | |
// 绘制干扰线 | |
for (let i = 0; i < 4; i++) { | |
ctx.strokeStyle = this._randomColor(40, 180) | |
ctx.beginPath() | |
ctx.moveTo(this._randomNumber(0, this.config.width / 2), this._randomNumber(0, this.config.height / 2)) | |
ctx.lineTo(this._randomNumber(0, this.config.width / 2), this._randomNumber(0, this.config.height)) | |
ctx.stroke() | |
} | |
// 绘制干扰点 | |
for (let i = 0; i < this.config.width / 4; i++) { | |
ctx.fillStyle = this._randomColor(0, 255) | |
ctx.beginPath() | |
ctx.arc(this._randomNumber(0, this.config.width), this._randomNumber(0, this.config.height), 1, 0, 2 * Math.PI) | |
ctx.fill() | |
} | |
} | |
validate(code) { | |
const verifyCode = code.toLowerCase() | |
const codeStr = this.config.code.toLowerCase() | |
if (verifyCode === codeStr) { | |
return true | |
} else { | |
return false | |
} | |
} | |
// 辅助方法 | |
_getAllLetter() { | |
const result = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z' | |
return result.split(',') | |
} | |
_randomNumber(min, max) { | |
return Math.floor(Math.random() * (max - min) + min) | |
} | |
_randomColor(min, max) { | |
const r = this._randomNumber(min, max) | |
const g = this._randomNumber(min, max) | |
const b = this._randomNumber(min, max) | |
return `rgb(${r}, ${g}, ${b})` | |
} | |
} | |
export default Verify |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment