【前端实践系列之十三】巧用canvas实现前端验证码

200 阅读1分钟

这是我参与更文挑战的第20天,活动详情查看: 更文挑战 !

👽 概论

形形色色的验证码,大家想必见到过很多,下图这种验证码是前几年较为常见的一种。这种验证码的实现过程也较为容易,仅用一点canvas技巧即可轻松实现。

image.png

当然,现在这种验证码已经不多见了,但借鉴思路从中学习canvas还是可以的。

👽 实现过程

直接说实现的总体思路:

1.  生成canvas背景上的干扰点;
2.  生成canvas背景上的干扰线;
3.  生成验证码;
4。 验证码优化。

实现代码如下:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas验证码</title>
    <style>
        canvas {
            margin: auto;
        }
    </style>
</head>
<body>
    <canvas width="400" height="150"></canvas>
    <script src='/index.js>
<body>

const canvas = document.querySelector("canvas");//选中canvas元素
const ctx = canvas.getContext("2d");//创建canvas画布

//生成最大为max的随机整数
function createRandomNumber(max, min = 0) {
  const range = max - min;
  const randomNum = Math.round(Math.random() * range) + min;
  return randomNum;
}

//生成透明度为opacity(为保证清晰,不得大于1小于0.4)的颜色
function createRandomColor(opacity) {
  return `rgba(${createRandomNumber(255)},${createRandomNumber(255)},${createRandomNumber(255)},${
    opacity < 0.4 ? 0.4 : opacity > 1 ? 1 : opacity
  })`;
}

//生成具有随机位置的干扰点
function createDot() {
  const xPosition = createRandomNumber(canvas.width);
  const yPosition = createRandomNumber(canvas.height);
  const color = createRandomColor(0.6);
  
  ctx.beginPath();
  ctx.arc(xPosition, yPosition, 2, 0, Math.PI * 2, false);
  ctx.fillStyle = color;
  ctx.strokeStyle = color;
  ctx.fill();
  ctx.stroke();
  ctx.closePath();
}

//生成具有随机位置随机颜色的干扰线
function createLine() {
  const color = createRandomColor(1);

  ctx.beginPath();
  ctx.moveTo(0, createRandomNumber(canvas.height));
  ctx.lineTo(canvas.width, createRandomNumber(canvas.height));
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();
}

//生成具有随机颜色的随机大写字母
function createText() {
  const xPosition = createRandomNumber(canvas.width - 60) + 30;
  const yPosition = createRandomNumber(canvas.height - 60) + 30;
  const color = createRandomColor(1);
  const text = String.fromCharCode(createRandomNumber(65, 90));

  ctx.font = "bold 30px '黑体'";
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillStyle = color;
  ctx.fillText(text, xPosition, yPosition);
}

//执行结果
(() => {
testText = '';
ctx.clearRect(0, 0, canvas.width, canvas.height);

for (let num = 1; num <= 50; num++) {
     createDot();
     if (num <= 5) {
       createLine();
       createText();
     }
}
})();