图形验证码(react+vue)版本

2022-08-11 19:39:42 浏览数 (1)

之前vue版本的博客里面找了一款图形验证的组件,

由于现在重新开发了react版本的博客

图型验证码 没有找到比较好的组件,

所以干脆看一下之前vue版本的图形验证码的源码

直接搬过来

先看一下效果图:

接下来直接上代码:

VUE版本:

组件源码:sidentify.vue

代码语言:javascript复制
<template>
  <div class="s-canvas">
    <!-- 验证码组件 -->
    <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  </div>
</template>
<script>
export default {
  name: "SIdentify",
  props: {
    identifyCode: {
      type: String,
      default: "1234"
    },
    fontSizeMin: {
      type: Number,
      default: 16
    },
    fontSizeMax: {
      type: Number,
      default: 40
    },
    backgroundColorMin: {
      type: Number,
      default: 180
    },
    backgroundColorMax: {
      type: Number,
      default: 240
    },
    colorMin: {
      type: Number,
      default: 50
    },
    colorMax: {
      type: Number,
      default: 160
    },
    lineColorMin: {
      type: Number,
      default: 40
    },
    lineColorMax: {
      type: Number,
      default: 180
    },
    dotColorMin: {
      type: Number,
      default: 0
    },
    dotColorMax: {
      type: Number,
      default: 255
    },
    contentWidth: {
      type: Number,
      default: 112
    },
    contentHeight: {
      type: Number,
      default: 38
    }
  },
  methods: {
    // 生成一个随机数
    randomNum(min, max) {
      return Math.floor(Math.random() * (max - min)   min);
    },
    // 生成一个随机的颜色
    randomColor(min, max) {
      let r = this.randomNum(min, max);
      let g = this.randomNum(min, max);
      let b = this.randomNum(min, max);
      return "rgb("   r   ","   g   ","   b   ")";
    },
    drawPic() {
      let canvas = document.getElementById("s-canvas");
      let ctx = canvas.getContext("2d");
      ctx.textBaseline = "bottom";
      // 绘制背景
      ctx.fillStyle = this.randomColor(
        this.backgroundColorMin,
        this.backgroundColorMax
      );
      ctx.fillRect(0, 0, this.contentWidth, this.contentHeight);
      // 绘制文字
      for (let i = 0; i < this.identifyCode.length; i  ) {
        this.drawText(ctx, this.identifyCode[i], i);
      }
      // this.drawLine(ctx);
      // this.drawDot(ctx);
    },
    drawText(ctx, txt, i) {
      ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
      ctx.font =
        this.randomNum(this.fontSizeMin, this.fontSizeMax)   "px SimHei";
      let x = (i   1) * (this.contentWidth / (this.identifyCode.length   1));
      let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5);
      var deg = this.randomNum(-45, 45);
      // 修改坐标原点和旋转角度
      ctx.translate(x, y);
      ctx.rotate((deg * Math.PI) / 180);
      ctx.fillText(txt, 0, 0);
      // 恢复坐标原点和旋转角度
      ctx.rotate((-deg * Math.PI) / 180);
      ctx.translate(-x, -y);
    }
    // drawLine(ctx) {
    //   // 绘制干扰线
    //   for (let i = 0; i < 8; i  ) {
    //     ctx.strokeStyle = this.randomColor(
    //       this.lineColorMin,
    //       this.lineColorMax
    //     );
    //     ctx.beginPath();
    //     ctx.moveTo(
    //       this.randomNum(0, this.contentWidth),
    //       this.randomNum(0, this.contentHeight)
    //     );
    //     ctx.lineTo(
    //       this.randomNum(0, this.contentWidth),
    //       this.randomNum(0, this.contentHeight)
    //     );
    //     ctx.stroke();
    //   }
    // },
    // drawDot(ctx) {
    //   // 绘制干扰点
    //   for (let i = 0; i < 100; i  ) {
    //     ctx.fillStyle = this.randomColor(0, 255);
    //     ctx.beginPath();
    //     ctx.arc(
    //       this.randomNum(0, this.contentWidth),
    //       this.randomNum(0, this.contentHeight),
    //       1,
    //       0,
    //       2 * Math.PI
    //     );
    //     ctx.fill();
    //   }
    // }
  },
  watch: {
    identifyCode() {
      this.drawPic();
    }
  },
  mounted() {
    this.drawPic();
  }
};
</script>
<style lang="css" scoped>
.s-canvas {
  height: 38px;
}
canvas {
  margin-top: 1px;
  margin-left: 8px;
}
</style>

引用:

代码语言:javascript复制
import SIdentify from "./sidentify";
      <!--验证码组件-->
// template 
<s-identify :identifyCode="123456789"></s-identify>
// v-data
   identifyCodes: "1234567890",
   identifyCode: "",
// v-methods
    randomNum(min, max) {
      return Math.floor(Math.random() * (max - min)   min);
    },
    refreshCode() {
      this.identifyCode = "";
      this.makeCode(this.identifyCodes, 4);
    },
    makeCode(o, l) {
      for (let i = 0; i < l; i  ) {
        this.identifyCode  = this.identifyCodes[
          this.randomNum(0, this.identifyCodes.length)
        ];
      }
    },
// v-created
  created() {
    this.refreshCode();
  },

下面是react版本:

代码语言:javascript复制
import React, { Component } from "react";

let defaultDataObj = {
  identifyCodes: {
    type: String,
    default: "1234567890",
  },
  identifyCode: {
    type: String,
    default: "1234",
  },
  fontSizeMin: {
    type: Number,
    default: 16,
  },
  fontSizeMax: {
    type: Number,
    default: 40,
  },
  backgroundColorMin: {
    type: Number,
    default: 180,
  },
  backgroundColorMax: {
    type: Number,
    default: 240,
  },
  colorMin: {
    type: Number,
    default: 50,
  },
  colorMax: {
    type: Number,
    default: 160,
  },
  lineColorMin: {
    type: Number,
    default: 40,
  },
  lineColorMax: {
    type: Number,
    default: 180,
  },
  dotColorMin: {
    type: Number,
    default: 0,
  },
  dotColorMax: {
    type: Number,
    default: 255,
  },
  contentWidth: {
    type: Number,
    default: 112,
  },
  contentHeight: {
    type: Number,
    default: 38,
  },
};
class SIdentify extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  // 生成一个随机数
  randomNum = (min, max) => {
    return Math.floor(Math.random() * (max - min)   min);
  };

  // 生成一个随机的颜色
  randomColor = (min, max) => {
    let r = this.randomNum(min, max);
    let g = this.randomNum(min, max);
    let b = this.randomNum(min, max);
    return "rgb("   r   ","   g   ","   b   ")";
  };

  drawPic = () => {
    let canvas = document.getElementById("s-canvas");
    let ctx = canvas.getContext("2d");

    console.log(canvas);
    console.log(ctx);
    ctx.textBaseline = "bottom";
    // 绘制背景

    console.log(defaultDataObj.backgroundColorMin);
    ctx.fillStyle = this.randomColor(
      defaultDataObj.backgroundColorMin.default,
      defaultDataObj.backgroundColorMax.default
    );
    ctx.fillRect(
      0,
      0,
      defaultDataObj.contentWidth.default,
      defaultDataObj.contentHeight.default
    );
    // 绘制文字
    for (let i = 0; i < defaultDataObj.identifyCode.default.length; i  ) {
      this.drawText(ctx, defaultDataObj.identifyCode.default[i], i);
    }

    this.drawLine(ctx);
    this.drawDot(ctx);
  };

  drawText = (ctx, txt, i) => {
    ctx.fillStyle = this.randomColor(
      defaultDataObj.colorMin.default,
      defaultDataObj.colorMax.default
    );
    ctx.font =
      this.randomNum(
        defaultDataObj.fontSizeMin.default,
        defaultDataObj.fontSizeMax.default
      )   "px SimHei";
    let x =
      (i   1) *
      (defaultDataObj.contentWidth.default /
        (defaultDataObj.identifyCode.default.length   1));
    let y = this.randomNum(
      defaultDataObj.fontSizeMax.default,
      defaultDataObj.contentHeight.default - 5
    );
    var deg = this.randomNum(-45, 45);
    // 修改坐标原点和旋转角度
    ctx.translate(x, y);
    ctx.rotate((deg * Math.PI) / 180);
    ctx.fillText(txt, 0, 0);
    // 恢复坐标原点和旋转角度
    ctx.rotate((-deg * Math.PI) / 180);
    ctx.translate(-x, -y);
  };

  drawLine = (ctx) => {
    // 绘制干扰线
    for (let i = 0; i < 8; i  ) {
      ctx.strokeStyle = this.randomColor(
        defaultDataObj.lineColorMin.default,
        defaultDataObj.lineColorMax.default
      );
      ctx.beginPath();
      ctx.moveTo(
        this.randomNum(0, defaultDataObj.contentWidth.default),
        this.randomNum(0, defaultDataObj.contentHeight.default)
      );
      ctx.lineTo(
        this.randomNum(0, defaultDataObj.contentWidth.default),
        this.randomNum(0, defaultDataObj.contentHeight.default)
      );
      ctx.stroke();
    }
  };

  drawDot(ctx) {
    // 绘制干扰点
    for (let i = 0; i < 100; i  ) {
      ctx.fillStyle = this.randomColor(0, 255);
      ctx.beginPath();
      ctx.arc(
        this.randomNum(0, this.contentWidth),
        this.randomNum(0, this.contentHeight),
        1,
        0,
        2 * Math.PI
      );
      ctx.fill();
    }
  }

  changeCode = () => {
    this.refreshCode();
  };

  makeCode = (o, l) => {
    for (let i = 0; i < l; i  ) {
      defaultDataObj.identifyCode.default  =
        defaultDataObj.identifyCodes.default[
          this.randomNum(0, defaultDataObj.identifyCodes.default.length)
        ];
    }

    console.log("校验", defaultDataObj.identifyCode.default);
    this.drawPic();
  };

  refreshCode = () => {
    defaultDataObj.identifyCode.default = "";
    this.makeCode(defaultDataObj.identifyCodes.default, 4);
  };

  render() {
    return (
      <div>
        验证码:
        <canvas id="s-canvas" width="112px" height="38"></canvas>
        <button onClick={this.changeCode}>切换验证码</button>
      </div>
    );
  }

  componentDidMount() {
    this.refreshCode();
  }
}

export default SIdentify;

逻辑都一样就是写法改了一下,

有问题可以留言

0 人点赞