手写一个校验码和验证框

  • 手写一个校验码和校验框

<template>
  <div>
    <canvas ref="captchaCanvas" :width="canvasWidth" :height="canvasHeight" @click="refreshCaptcha"></canvas>
    <input type="text" v-model="inputValue" @keyup.enter="checkCaptcha">
  </div>
</template>

<script>
export default {
  props: {
    captchaLength: {
      type: Number,
      default: 4 // 默认验证码长度为4
    },
    canvasWidth: {
      type: Number,
      default: 100 // 默认画布宽度为100
    },
    canvasHeight: {
      type: Number,
      default: 40 // 默认画布高度为40
    },
    font: {
      type: String,
      default: '20px Arial' // 默认字体样式
    },
    textColor: {
      type: String,
      default: '#000' // 默认文本颜色为黑色
    },
    bgColor: {
      type: String,
      default: '#fff' // 默认背景颜色为白色
    },
    lineColor: {
      type: String,
      default: '#000' // 默认干扰线颜色为黑色
    },
    lineWidth: {
      type: Number,
      default: 1 // 默认干扰线宽度为1
    }
  },
  data() {
    return {
      captchaText: '', // 图形验证码的文本
      inputValue: '', // 用户输入的值
      isInputEntered: false // 用户是否输入完成标志
    };
  },
  mounted() {
    this.generateCaptcha();
  },
  watch: {
    inputValue(value) {
      if (value === this.captchaText && this.isInputEntered) {
        this.checkCaptcha();
      }
    }
  },
  methods: {
    // 生成图形验证码
    generateCaptcha() {
      const canvas = this.$refs.captchaCanvas;
      const ctx = canvas.getContext('2d');

      // 生成随机验证码文本
      this.captchaText = this.generateRandomString(this.captchaLength);

      // 绘制验证码背景
      ctx.fillStyle = this.bgColor;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // 绘制干扰线
      for (let i = 0; i < 5; i++) {
        this.drawRandomLine(ctx);
      }

      // 绘制验证码文本
      for (let i = 0; i < this.captchaText.length; i++) {
        const char = this.captchaText.charAt(i);
        const x = (i + 1) * (canvas.width / (this.captchaLength + 1));
        const y = canvas.height / 2;
        this.drawText(ctx, char, x, y);
      }
    },
    // 绘制随机干扰线
    drawRandomLine(ctx) {
      const canvas = this.$refs.captchaCanvas;
      const x1 = Math.random() * canvas.width;
      const y1 = Math.random() * canvas.height;
      const x2 = Math.random() * canvas.width;
      const y2 = Math.random() * canvas.height;
      const color = this.generateRandomColor(); // 随机颜色

      ctx.strokeStyle = color;
      ctx.lineWidth = this.lineWidth;
      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.stroke();
    },
    // 绘制验证码文本
    drawText(ctx, char, x, y) {
      const color = this.generateRandomColor(); // 随机颜色
      const rotation = Math.random() * 30 - 15; // 随机旋转角度,范围为 -15 到 15 度

      ctx.font = this.font;
      ctx.fillStyle = color;
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(rotation * Math.PI / 180); // 将角度转换为弧度
      ctx.fillText(char, 0, 0);
      ctx.restore();
    },
    // 刷新验证码
    refreshCaptcha() {
      this.generateCaptcha();
    },
    // 校验验证码
    checkCaptcha() {
      if (this.inputValue.toLowerCase() === this.captchaText.toLowerCase()) {
        alert('验证码正确!');
      } else {
        alert('验证码错误!');
        this.inputValue = ''; // 清空输入框
        this.generateCaptcha(); // 重新生成验证码
      }
    },
    // 生成指定长度的随机字符串
    generateRandomString(length) {
      const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      let result = '';
      for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * characters.length));
      }
      return result;
    },
    // 生成随机颜色
    generateRandomColor() {
      return '#' + Math.floor(Math.random() * 16777215).toString(16); // 生成随机的十六进制颜色值
    }
  }
};
</script>

image

先这样吧

后面补

posted @ 2024-05-09 09:42  茫茫人间刺骨凉  阅读(23)  评论(0)    收藏  举报