前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图形验证码(react+vue)版本

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

作者头像
biaoblog.cn 个人博客
发布2022-08-11 19:39:42
6400
发布2022-08-11 19:39:42
举报

之前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;

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

有问题可以留言

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • VUE版本:
  • 下面是react版本:
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档