文档章节

前端验证码绘制(canvas)

lonelydawn
 lonelydawn
发布于 2017/04/11 01:15
字数 747
阅读 242
收藏 1

一切尽在代码中

js文件

/** 
 * canvas绘制动画浮动验证码
 * code by lonelydawn 2017-04-10
 */

var createVeritification = function(){
	var GLOBAL_CHAR_NUM = 4;
	var GLOBAL_CHAR_STRING = "";
	var GLOBAL_COLOR_SET = [
		"#FFFFFF", "#DDDDDD", "#AAAAAA", "#888888", "#666666", "#444444", "#000000",
		"#FFB7DD", "#FF88C2", "#FF44AA", "#FF0088", "#C10066", "#A20055", "#8C0044",
		"#FFCCCC", "#FF8888", "#FF3333", "#FF0000", "#CC0000", "#AA0000", "#880000",
		"#FFC8B4", "#FFA488", "#FF7744", "#FF5511", "#E63F00", "#C63300", "#A42D00",
		"#FFDDAA", "#FFBB66", "#FFAA33", "#FF8800", "#EE7700", "#CC6600", "#BB5500",
		"#FFEE99", "#FFDD55", "#FFCC22", "#FFBB00", "#DDAA00", "#AA7700", "#886600",
		"#FFFFBB", "#FFFF77", "#FFFF33", "#FFFF00", "#EEEE00", "#BBBB00", "#888800",
		"#EEFFBB", "#DDFF77", "#CCFF33", "#BBFF00", "#99DD00", "#88AA00", "#668800",
		"#CCFF99", "#BBFF66", "#99FF33", "#77FF00", "#66DD00", "#55AA00", "#227700",
		"#99FF99", "#66FF66", "#33FF33", "#00FF00", "#00DD00", "#00AA00", "#008800",
		"#BBFFEE", "#77FFCC", "#33FFAA", "#00FF99", "#00DD77", "#00AA55", "#008844",
		"#AAFFEE", "#77FFEE", "#33FFDD", "#00FFCC", "#00DDAA", "#00AA88", "#008866",
		"#99FFFF", "#66FFFF", "#33FFFF", "#00FFFF", "#00DDDD", "#00AAAA", "#008888",
		"#CCEEFF", "#77DDFF", "#33CCFF", "#00BBFF", "#009FCC", "#0088A8", "#007799",
		"#CCDDFF", "#99BBFF", "#5599FF", "#0066FF", "#0044BB", "#003C9D", "#003377",
		"#CCCCFF", "#9999FF", "#5555FF", "#0000FF", "#0000CC", "#0000AA", "#000088",
		"#CCBBFF", "#9F88FF", "#7744FF", "#5500FF", "#4400CC", "#2200AA", "#220088",
		"#D1BBFF", "#B088FF", "#9955FF", "#7700FF", "#5500DD", "#4400B3", "#3A0088",
		"#E8CCFF", "#D28EFF", "#B94FFF", "#9900FF", "#7700BB", "#66009D", "#550088",
		"#F0BBFF", "#E38EFF", "#E93EFF", "#CC00FF", "#A500CC", "#7A0099", "#660077",
		"#FFB3FF", "#FF77FF", "#FF3EFF", "#FF00FF", "#CC00CC", "#990099", "#770077"
	];

	var chars = [];
	var ctx = undefined;
	var timer = undefined;
	var canvasWidth = 1000;
	var canvasHeight = 500;

	// 获取canvas 上下文环境
	var getContext = function(){
		var canvas = document.getElementById("canvas");
		ctx =canvas.getContext("2d");
		canvasWidth = canvas.width;
		canvasHeight = canvas.height;
		return ctx;
	};

	// 获取单个字符, 字符范围 0-9 A-Z a-z 
	var getChar = function(){
		var char = '';
		// 返回 0- 61之间的整数
		var seed = Math.floor(Math.random()*62);

		if(seed < 10)			// seed 在 0- 9之间,字符为数字
			char = Math.floor(Math.random()*10);
		else if(seed < 36)	// seed 在10-35之间,字符为大写字母
			char = String.fromCharCode(Math.floor(Math.random()*25.99)+65);
		else if(seed < 62)	// seed 在36-62之间,字符为小写字母
			char = String.fromCharCode(Math.floor(Math.random()*25.99)+97);
		return char;
	};

	// 将单个字符封装为对象
	var getPackageChars = function(){
		for(var i=0; i<GLOBAL_CHAR_NUM; i++){
			chars[i] = {
				"x": canvasWidth/GLOBAL_CHAR_NUM*i,
				"y": canvasHeight/10*7,
				"size": Math.floor(((canvasWidth/GLOBAL_CHAR_NUM > canvasHeight)?
					canvasHeight:canvasWidth)*8/10),
				"char": getChar(),
				"color": GLOBAL_COLOR_SET[Math.floor(Math.random()*(GLOBAL_COLOR_SET.length-0.01))]
			};
			// 字符位置移动控制 bar
			chars[i].posCtrl = (i%2 == 0)? -1: 1;
		}
		return chars;
	};

	// 检测验证码是否正确
	var veritificate = function(code){
		var txt = "";
		for(var i=0;i<GLOBAL_CHAR_NUM;i++)
			txt += chars[i].char;
		return txt.toUpperCase() == code.toUpperCase();
	};

	// 绘制字符
	var draw = function(){
		// 清空 画布
		ctx.clearRect(0,0,canvasWidth,canvasHeight);
		// 绘制 浅灰色背景
		ctx.fillStyle = "#eee";
		ctx.fillRect(0, 0, canvasWidth, canvasHeight );
		// 绘制 字符
		// ctx.font="72px Microsoft YaHei";
		ctx.font="84px Georgia";
		for(var i=0;i<GLOBAL_CHAR_NUM;i++){
			ctx.strokeStyle = chars[i].color;
			ctx.strokeText(chars[i].char,chars[i].x,chars[i].y);
		}
	};

	// 字体动画效果
	var animation = function(){
		// 初始化 timer
		clearInterval(timer);

		timer = setInterval(function(){
			// 动态改变字符位置
			for(var i=0;i<GLOBAL_CHAR_NUM;i++){
				chars[i].y += chars[i].posCtrl;
					if(chars[i].y < canvasHeight * 5/10 || chars[i].y > canvasHeight * 9/10)
						chars[i].posCtrl = -chars[i].posCtrl;
			}
			// 重绘字符
			draw();
		},50);
	};

	// 创建静态字体 canvas
	var createStatic = function(){
		console.log(getContext());
		console.log(getPackageChars());
		draw();
	};

	// 创建动画字体 canvas
	var createAnimation = function(){
		getContext();
		getPackageChars();
		animation();
	};

	return{
		"createStatic": createStatic,
		"createAnimation": createAnimation,
		"veritificate": veritificate
	}
};


var test = new createVeritification();
test.createAnimation();
// test.createStatic();

// 点击刷新验证码
var toggleVeritification = function(){
	test.createAnimation();
};

// 验证输入是否正确
var checkCode = function(){
	// do sth...
	if(test.veritificate(document.getElementById("txt").value))
		alert(true);
	else alert(false);
};

 

html代码

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>验证码</title>
	<style type="text/css">
		span{
			color:#555;
		}
		span:hover{
			color:#777;
		}
	</style>
</head>
<body>
	<div>
		<canvas id="canvas" style="width:100px;height:26px;">你的浏览器不支持canvas,请更换浏览器!</canvas>
		<span onclick="toggleVeritification();">点击刷新</span>
	</div>
	<div>
		<input id="txt" type="text"/>
	</div>
	<div>
		<button onclick="checkCode();">验证</button>
	</div>
	<script type="text/javascript" src="index.js"></script>
</body>
</html>

 

本例可自动适配各种尺寸canvas

 

运行结果:

© 著作权归作者所有

共有 人打赏支持
lonelydawn
粉丝 41
博文 50
码字总数 52905
作品 0
闵行
前端工程师
私信 提问
vue-swiper的使用教程

在通常的登录界面我们都可以看到验证码,验证码的作用是检测是不是人在操作,防止机器等非人操作,防止数据库被轻而易举的攻破。 验证码一般用PHP和java等后端语言编写。 但是在前端,用can...

peakedness丶
2018/11/09
0
0
使用canvas在前端实现图片合成

看着总结的不错,我也就拿来主义了,做个记录,侵权必删 图片合成最常见的需求有验证码图片,亦或者图片加水印等,这种实现一般都是后端实现的。 随着HTML5发展和现代浏览器的占比越来越高,...

xllily_11
2018/02/26
0
0
php绘制图片验证码

验证码是一种安全保护机制,在注册时要求必须有人工操作进行验证,用于防止垃圾注册机大量注册用户账号占用服务器内存从而使服务器瘫痪。 图片验证码的实现十分简单。首先从指定字符集合中随...

lonelydawn
2016/04/12
3K
16
Canvas 都坐下,基本操作

前言 从最开始小白使用canvas采坑无数,让自己也积累了些还不错的想法,这期内容也是给自己做了些canvas api整理,以及需要注意的地方 参考网站 MDN 文章链接 微信H5实现网页长按保存图片及识...

MrZss
02/26
0
0
技术干货:前端图形化技术简介(上)

Canvas与SVG 前端图形化技术,主要包括Canvas绘图和SVG绘图两类。 Canvas早在十几年前就被火狐浏览器引入。Canvas通过Canvas.getContext(2d/3d)获得绘图上下文,采用绘制路径、填充路径、描边...

DataHunter小数
2017/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Hibernate SQLite方言

以下代码有参考过github上国外某位大佬的,在发文的最新稳定版Hibernate上是可用的,有时间再仔细分析一下 import org.hibernate.dialect.Dialect;import org.hibernate.dialect.function.S...

CHONGCHEN
今天
3
0
CentOS 7 MariaDB搭建主从服务器

本文编写环境为CentOS7。确保关闭SELinux,关闭防火墙或者防打开指定端口。具体信息如下 #master[root@promote ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [r...

白豆腐徐长卿
今天
10
0
介绍python中运算符优先级

下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合)。这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部...

问题终结者
今天
3
0
Spring Boot 2.x基础教程:快速入门

简介 在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot来让...

程序猿DD
昨天
10
0
SpringSecurity认证流程源码级详解

SpringSecurity认证流程源码级详解 认证流程说明 认证结果如何在多个请求之间共享 获取认证用户信息

chendom
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部