玩转Canvas:快速构建有趣验证码

1,338 阅读3分钟

引言

大家好,今天我要和大家分享如何利用Canvas快速构建有趣的验证码!在网络世界中,验证码是保护网站安全的重要手段之一。而通过Canvas技术,我们不仅可以轻松创建验证码,还能让它更加有趣和独特。接下来,让我们一起来探索构建Canvas验证码的乐趣吧!

构建canvas画布

首先,我们需要构建一个Canvas画布。通过HTML5中的<canvas>标签,我们可以创建一个绘图区域,用于展示我们的验证码。在这个画布上,我们将会绘制出随机的背景色、验证码字符、干扰线和干扰点,让整个验证码看起来更加复杂多变。

     <canvas id="canvas" width="120" height="40"></canvas>

随机背景色

接着,我们可以通过JavaScript随机生成背景色。利用RGB颜色模式,我们可以生成各种各样丰富多彩的背景色,为验证码增添背景视觉干扰。

// 生成[min,max)之间的随机数
function randomNum(min, max) {
    return Math.floor(Math.random() * (max - min) + min)
}

// 生成随机颜色
function randomColor(min, max) {
    let r = randomNum(min, max)
    let g = randomNum(min, max)
    let b = randomNum(min, max)
    return `rgb(${r},${g},${b}`;
}
        
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");

// 背景填充色 随机
ctx.fillStyle = randomColor(70, 230)
ctx.fillRect(0, 0, canvas.width, canvas.height)
  1. randomNum(min, max) 函数:

用于生成一个介于 [min, max) 范围内的随机整数。

利用 Math.random() 方法生成一个 [0, 1) 之间的随机数,然后将这个随机数乘以 (max - min) 得到一个在 [0, max - min) 范围内的随机数,再加上 min 得到最终的随机数。最后,使用 Math.floor() 取整以确保结果为整数。

  1. randomColor(min, max) 函数:

调用三次randomNum(min, max) ,分别生成 RGB 颜色中的红、绿、蓝三个分量的随机值,然后将这些值组合成一个 RGB 颜色字符串返回。

效果图:

image.png

随机验证码

接下来是生成随机验证码字符的环节。我们可以通过设定字符集,并随机选择字符来构建验证码。不仅如此,我们还可以对验证码字符进行旋转、变换大小等操作,使其看起来更加复杂。

// 随机生成字符串
// 字符池
const pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
// 存储生成的随机验证码
let imgCode = ''
// 生成 4 位验证码
for (let i = 0; i < 4; i++) {
    const text = pool[randomNum(0, pool.length)]
    imgCode += text
    // 随机字体大小
    const fontSize = randomNum(18, 40)
    ctx.font = `${fontSize}px Simhei`
    // 计算随机旋转角度
    const deg = randomNum(-30, 30)
    // 设置文本基线为顶部
    ctx.textBaseline = 'top'
    // 随机字体颜色
    ctx.fillStyle = randomColor(80, 150)
    // 将当前状态封存入栈
    ctx.save()  
    // 随机偏移距离
    ctx.translate(30 * i + 15, 15)
    // 随机旋转角度
    ctx.rotate((deg * Math.PI) / 180)
    // 位置相对于当前状态,左偏移10,上偏移15
    ctx.fillText(text, -10, -15)
    // 恢复之前保存的绘图状态
    ctx.restore() 

}

效果图:

image.png

随机干扰线和干扰点

此外,我们可以添加随机干扰线和干扰点,增加验证码的难度和安全性。

// 绘制干扰线
const lines = randomNum(5, 10);

for (let i = 0; i < lines; i++) {
    ctx.beginPath()
    ctx.moveTo(randomNum(0, canvas.width), randomNum(0, canvas.height))
    ctx.lineTo(randomNum(0, canvas.width), randomNum(0, canvas.height))
    ctx.strokeStyle = randomColor(100, 200)
    ctx.closePath()
    ctx.stroke()
}

// 绘制干扰点
const point = randomNum(90, 150);

for (let i = 0; i < point; i++) {
    ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1);
}

  1. 绘制干扰线部分
  • 使用 randomNum 函数生成 5 - 10 条干扰线。
  • 使用 ctx.beginPath() 开始一条新的路径。
  • 使用 ctx.moveTo(randomNum(0, canvas.width), randomNum(0, canvas.height)) 将起点移动到随机的坐标位置。
  • 使用 ctx.lineTo(randomNum(0, canvas.width), randomNum(0, canvas.height)) 在随机的终点添加一条线段。
  • 使用 ctx.strokeStyle = randomColor(100, 200) 设置线条的颜色为随机生成的颜色。
  • 使用 ctx.closePath() 封闭路径。
  • 最后,使用 ctx.stroke() 绘制干扰线。
  1. 绘制干扰点部分
  • 使用 randomNum 函数生成 90 - 150个干扰点。
  • 对于每个干扰点,使用 ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1) 在随机位置绘制一个像素大小的填充矩形,作为干扰点。

效果图:

image.png

点击重新生成

最后,由于生成的随机性,可能会导致一些验证码肉眼难以识别,所以和大多数验证码一样,添加一个点击重新生成验证码功能。

将上方非函数代码封装到一个draw函数中,再使用 onclick 调用这个函数,就可以非常简单快速的实现点击重新生成。

<canvas id="canvas" width="120" height="40" onclick="draw()"></canvas>

总结

通过以上步骤,我们成功地利用Canvas技术构建了一个独特而有趣的验证码。通过不断尝试和调整,我们可以创造出各种形式各样的验证码。当然Canvas的运用远不止如此,它为我们提供了无尽的可能性和创新空间。除了用于创建验证码系统,Canvas还可以用于实现各种交互式设计和动态效果,为用户提供更加丰富和有趣的体验。如果你觉得这篇文章有帮助或有所启发,别忘了给我一个鼓励的