svg-captcha确实是很好用的一个验证码生成库,它可以帮助我们快捷生成各类字符和简单算术验证码。
然而我在一个项目的使用中却发现传入width和height参数后,验证码出现显示不全,十分影响用户辨识的情况。
刚开始我是先通过ignoreChars来对容易显示不全的字符进行过滤,后来感觉这总归不是个长久之法,于是打算从源码入手找到问题所在。
在/node_modules/svg-captcha/lib/index.js
的27行,我找到了生成字符图片的getText函数。
const getText = function (text, width, height, options) {
const len = text.length;
const spacing = (width - 2) / (len + 1);
const min = options.inverse ? 10 : 0;
const max = options.inverse ? 14 : 4;
let i = -1;
const out = [];
while (++i < len) {
// 此处代表生成文字在背景里的起始坐标。
const x = spacing * (i + 1);
const y = height / 2;
const charPath = chToPath(text[i], Object.assign({x, y}, options));
const color = options.color ?
random.color(options.background) : random.greyColor(min, max);
out.push(`<path fill="${color}" d="${charPath}"/>`);
}
return out;
};
我们看到在while循环里,使用x和y定义生成文字在背景里的起始坐标。我们的文字要向上偏移,经过我的测试,将分母的2修改为3即可。即const y = height / 3;
这里可以根据自己的感受自己调整,后面的数字越大,字符就越向上偏移,可以使用小数。
修改完成后,看看现在的显示效果,已经舒服多了。
然而部分小写字符,还是会出现部分残缺,这是由于本身小写英文字母的沉底特性决定的,建议还是要加上ignoreChars: '0o1iILlpPyq'
,这是我总结的几个比较容易识别错误的。
如果对验证码的复杂度要求不高的话,可以不用ignoreChars
参数,直接使用charPreset: '012345689'
来使生成的验证码里只有自己预设的字符。