JavaScript Canvas实现验证码
程序员文章站
2023-08-11 22:13:13
在通常的登录界面我们都可以看到验证码,验证码的作用是检测是不是人在操作,防止机器等非人操作,防止数据库被轻而易举的攻破。
验证码一般用php和java等后端语言编写。...
在通常的登录界面我们都可以看到验证码,验证码的作用是检测是不是人在操作,防止机器等非人操作,防止数据库被轻而易举的攻破。
验证码一般用php和java等后端语言编写。
但是在前端,用canva或者svg也可以绘制验证码。
绘制验证码不能是简单的随机字符串,而应该在绘制界面有一些干扰项:
如:干扰线段、干扰圆点、背景等等。
这里的这个demo的canvas验证码干扰项比较简单。
可以在图示中看到本例中的干扰项。
canvas验证码展示效果:
点击实现改变(重绘)验证码:
在控制台运行函数输出返回值(验证码):
源码 :
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>canvas验证码</title> </head> <body> <canvas width="200" height="60" id="check" style="border:1px solid #000;">您的浏览器不支持canvas标签!</canvas> <script> var ctx = document.getelementbyid("check").getcontext("2d"); var ctxw = document.getelementbyid("check").clientwidth; var ctxh = document.getelementbyid("check").clientheight; /** * 产生一个随机数 可设置随机数区间 * @param {[number]} min [随机数区间下限] * @param {[number]} max [随机数区间上限] * @return {[number]} [返回一个在此区间的随机数] */ function rannum(min, max) { return math.random() * (max - min) + min; } /** * 返回一个随机颜色 可设置颜色区间 * @param {[number]} min [颜色下限] * @param {[number]} max [颜色上限] * @return {[string]} [随机颜色] */ function rancolor(min, max) { var r = rannum(min, max); var g = rannum(min, max); var b = rannum(min, max); // return "rgb(" + r + "," + g + "," + b + ")"; return `rgb(${r},${g},${b})`; } /** * 随机字符串数组 * @return {[array]} [随机数组] */ function ranstr() { var str = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm0123456789"; return str.split("").sort(function () { return math.random() - 0.5 }); } /** * 绘制文本字符串 * @param {[string]} canvasid [canvas的id] * @param {[number]} canvasw [canvas的width] * @param {[number]} canvash [canvas的height] * @param {[number]} num [绘制验证码的字数] * @param {[number]} fsmin [字体大小下限] * @param {[number]} fsmax [字体大小上限] * @param {[number]} frmin [字体旋转偏移下限] * @param {[number]} frmax [字体旋转偏移上限] * @param {[number]} min [颜色下限] * @param {[number]} max [颜色上限] * @return {[string]} [随机字符串] */ function drawtext(canvasid, canvasw, canvash, num, fsmin, fsmax, frmin, frmax, min, max) { var str = ""; for (var i = 0; i < num; i++) { var char = ranstr()[math.floor(0, ranstr().length)]; var fs = rannum(fsmin, fsmax); canvasid.font = fs + "px verdana"; canvasid.fillstyle = rancolor(min, max); // 保存绘制的状态 canvasid.save(); // context.translate(x,y); // x 添加到水平坐标(x)上的值 // y 添加到垂直坐标(y)上的值 // 偏移 canvasid.translate(canvasw / num * i + canvasw / 20, 0); // 变换角度 canvasid.rotate(rannum(frmin, frmax) * math.pi / 180); // context.filltext(text,x,y,maxwidth); // text 规定在画布上输出的文本。 // x 开始绘制文本的 x 坐标位置(相对于画布)。 // y 开始绘制文本的 y 坐标位置(相对于画布)。 // maxwidth 可选。允许的最大文本宽度,以像素计。 canvasid.filltext(char, 0, (canvash + fs) / 2.5, canvasw / num); // 返回之前保存过的路径状态和属性 ctx.restore(); str += char; } // console.log(str); return str; } /** * 绘制背景 * @param {[string]} canvasid [canvas的id] * @param {[number]} canvasw [canvas的width] * @param {[number]} canvash [canvas的height] * @param {[number]} min [下限] * @param {[number]} max [上限] */ function drawbg(canvasid, canvasw, canvash, min, max) { // 绘制canvas背景 canvasid.fillstyle = rancolor(min, max); // 填充颜色 canvasid.fillrect(0, 0, canvasw, canvash); } /** * 绘制干扰 圆点 * @param {[string]} canvasid [canvas的id] * @param {[number]} canvasw [canvas的width] * @param {[number]} canvash [canvas的height] * @param {[number]} num [绘制的数量] * @param {[number]} r [圆点半径] * @param {[number]} min [下限] * @param {[number]} max [上线] */ function drawcircle(canvasid, canvasw, canvash, num, r, min, max) { for (var i = 0; i < num; i++) { // 开始绘制 (拿起笔) canvasid.beginpath(); // context.arc(x,y,r,sangle,eangle,counterclockwise); (绘制) // x 圆的中心的 x 坐标。 // y 圆的中心的 y 坐标。 // r 圆的半径。 // sangle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。 // eangle 结束角,以弧度计。 // counterclockwise 可选。规定应该逆时针还是顺时针绘图。false = 顺时针,true = 逆时针。 canvasid.arc(rannum(0, canvasw), rannum(0, canvash), r, 0, 2 * math.pi); // 填充颜色 canvasid.fillstyle = rancolor(min, max); // 填充 canvasid.fill(); // 闭合绘制 (放开笔) canvasid.closepath(); } } /** * 绘制干扰 线段 * @param {[string]} canvasid [canvas的id] * @param {[number]} canvasw [canvas的width] * @param {[number]} canvash [canvas的height] * @param {[number]} num [绘制的数量] * @param {[number]} min [下限] * @param {[number]} max [上线] */ function drawline(canvasid, canvasw, canvash, num, min, max) { for (var i = 0; i < num; i++) { // 开始绘制 (拿起笔) canvasid.beginpath(); // 绘制开始点 canvasid.moveto(rannum(0, canvasw), rannum(0, canvash)); // 绘制结束点 canvasid.lineto(rannum(0, canvasw), rannum(0, canvash)); canvasid.strokestyle = rancolor(min, max); canvasid.stroke(); canvasid.closepath(); } } // 绘制验证码 function drawcanvas() { // 清空canvas ctx.clearrect(0, 0, 200, 60); // 绘制背景 drawbg(ctx, ctxw, ctxh, 200, 255); // 绘制干扰圆点 drawcircle(ctx, ctxw, ctxh, 20, 5, 200, 255); // 绘制干扰线段 drawline(ctx, ctxw, ctxh, 20, 0, 255); // 绘制验证码 var str = drawtext(ctx, ctxw, ctxh, 4, 10, 50, -30, 30, 0, 100); return str; } drawcanvas(); document.getelementbyid('check').onclick = drawcanvas; </script> </body> </html>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 微信小程序实现自定义加载图标功能