-
Notifications
You must be signed in to change notification settings - Fork 11
/
captcha.js
73 lines (65 loc) · 2.93 KB
/
captcha.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
var Canvas = require('canvas');
module.exports = function(config, callback){
config.fileMode = config.fileMode || 0;
config.size = config.size || 4;
config.height = config.height || 24;
config.width = config.width || config.height * config.size;
config.color = config.color || 'rgb(0,0,0)';
config.background = config.background || 'rgb(255,255,255)';
config.lineWidth = config.lineWidth || 2;
config.saveDir = config.saveDir || __dirname;
config.text = config.text || ('' + Math.random()).substr(2, config.size);
config.noise = (config.noise !== false) ? true : false;
config.noiseColor = config.noiseColor || config.color;
config.complexity = config.complexity || 3;
config.complexity = (config.complexity < 1 || config.complexity > 5) ? 3 : config.complexity;
config.spacing = config.spacing || 2;
config.spacing = (config.spacing < 1 || config.spacing > 3) ? 2 : config.spacing;
var fontSize = Math.round(config.height * 0.5 + (15 - config.complexity * 3));
var canvas = new Canvas(config.width, config.height);
var ctx = canvas.getContext('2d');
ctx.fillStyle = config.background;
ctx.fillRect(0, 0, config.width, config.height);
ctx.fillStyle = config.color;
ctx.lineWidth = config.lineWidth;
ctx.font = fontSize +'px sans';
if (config.noise) {
ctx.strokeStyle = config.noiseColor;
var noiseHeight = config.height;
for (var i = 0; i < 2; i++) {
ctx.moveTo(20, Math.random() * noiseHeight);
ctx.bezierCurveTo(80, Math.random() * noiseHeight, 160, Math.random() * noiseHeight, 230, Math.random() * noiseHeight);
ctx.stroke();
}
}
var modifier = config.complexity / 5;
ctx.strokeStyle = config.color;
for (i = 0; i < config.text.length; i++) {
ctx.setTransform(Math.random() * modifier + 1 + modifier/3, Math.random() * modifier + modifier/3,
Math.random() * modifier + modifier/3, Math.random() * modifier + 1 + modifier/3,
(config.height * i)/(4-config.spacing) + (config.height-fontSize)/3 + 10, config.height-(config.height-fontSize)/2);
ctx.fillText(config.text.charAt(i), 0, 0);
}
if (1 == config.fileMode) {
var fs = require('fs');
var filename = new Date().getTime() + Math.floor(Math.random()*1000) +'.png';
var out = fs.createWriteStream(config.saveDir +"/"+ filename);
var stream = canvas.pngStream();
stream.on('data', function(chunk){
out.write(chunk);
});
stream.on('end', function(){
callback(config.text, filename);
});
}
else if (2 == config.fileMode) {
canvas.toBuffer(function(err, buf) {
callback(config.text, buf);
});
}
else {
canvas.toDataURL('image/png', function(err, data){
callback(config.text, data);
});
}
};