前端验证码绘制(canvas)

一切尽在代码中

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

运行结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

1.2K8
来自专栏c#开发者

在DataGrid中选择,确认,删除多行复选框列表

在DataGrid中选择,确认,删除多行复选框列表 Selecting, Confirming & Deleting Mul...

3787
来自专栏菩提树下的杨过

Flash/Flex学习笔记(40):弹性运动续--弹簧

上一篇里演示的弹性运动加上摩擦力因素后,物体最终基本上都会比较准确的停在目标位置。但是我们回想一下现实世界中的弹簧,如果把弹簧的一头固定起来(即相当于目标点),...

2015
来自专栏菩提树下的杨过

PixelBender(着色器)初体验

只要是玩过photoshop的人,一定会对ps中的各式各样、功能强大的滤镜(filter)留下深刻的印象。 Adobe是靠图形处理软件起家的,这方面一直是它的强...

2906
来自专栏c#开发者

XML Encryption in .Net

XML Encryption in .Net One of the new features being introduced with the Whidbey...

4637
来自专栏程序你好

在WPF桌面程序中使用ECharts展示图表

2683
来自专栏码匠的流水账

聊聊rocketmq的RequestTask

org/apache/rocketmq/remoting/netty/RequestTask.java

2052
来自专栏跟着阿笨一起玩NET

从sql server 中读取二进制图片

1751
来自专栏叁金大数据

EmguCV学习——视频与图片互转

其实视频转图片在上篇文章中已经有些眉目了,其实就是按帧读取视频,然后把帧保存就ok。然后自己再加个进度条美化一下。。。这代码简单易懂,还是直接上代码吧。

2371
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(三):基本模块调用

搞定基本的函数之后,开始鼓捣SAS里面的模型。也就是说,要开始写PROC了。说实话,越学SAS,越觉得SAS像Stata...无论是从输出的样式,还是语法。好不...

3325

扫码关注云+社区

领取腾讯云代金券