This website requires JavaScript.
原创

Canvas之生成验证码

2020.01.03 11:19 

5 人喜欢
804 次阅读
10 条评论

其实在做验证码这块时,想到过用js配合html、css来生成一段验证码dom,后面想了想,用户一F12打开控制台,选中对应的点上,就能复制粘贴,可靠性还是有丶水的

好,既然水就换高级点的,画图!Canvas!

最终效果图

小二,上码!

一、先引入个canvas标签

<canvas ref="canvasCode" width="200px" height="40px"></canvas>

二、编写JS代码进行生成

clearCanvas() { 
      //清除绘制*******用户点击更换验证码时,canvas中的内容需要清掉
      let canvas = this.$refs["canvasCode"];
      let canvasCode = canvas.getContext("2d");
      canvasCode.fillStyle = "#FFF";
      canvasCode.fillRect(0, 0, canvas.width, canvas.height);
}
drawLine(canvasCode) {
      //绘制背景潦草线条
      for (let i = 0; i < 20; i++) {
        //i < 20即绘制20条潦草线条作为混杂因素
        canvasCode.beginPath(); //开始一个路径
        canvasCode.moveTo(Math.random() * 200, Math.random() * 40); //设置起点坐标
        canvasCode.lineTo(Math.random() * 200, Math.random() * 40); //设置终点坐标
        canvasCode.strokeStyle = "#27ba5a"; //线条颜色
        canvasCode.stroke(); //开始绘制
      }
}
drawText(canvasCode) {
      //绘制验证码
      let codeStr = ""; //验证码内容

      for (let i = 0; i < this.codeLength; i++) { //this.codeLength是要生成几个验证码内容
        //绘制随机汉字
        const x = 20 + i * 20; //x轴位置
        const y = 15 + Math.random() * 10; //y轴位置
        const deg = (180 * Math.random() * Math.PI) / 180 / 2; //文字内容的旋转角度
        const singleWord = this.chineseStr[
          Math.floor(Math.random() * this.chineseStr.length)
        ]; //获取的随机单字
        codeStr += singleWord;
        canvasCode.font = "16px 微软雅黑"; //文字格式
        canvasCode.fillStyle = "red"; //文字颜色
        canvasCode.translate(x, y); //文字所在的位置
        canvasCode.rotate(deg); //文字旋转一哈
        canvasCode.fillText(singleWord, 0, 0); //写入文字
        canvasCode.rotate(-deg); //恢复一下文字旋转度数,不然翻车
        canvasCode.translate(-x, -y); //恢复一下文字所在的位置操作,不然翻车
      }

      return codeStr;
}
getCode() {
      //验证码生成
      this.clearCanvas(); //清除上一波的绘制
      let canvasCode = this.$refs["canvasCode"].getContext("2d");
      this.drawLine(canvasCode); //绘制线条
      let codeStr = this.drawText(canvasCode); // 绘制验证码
}
//然后调用下getCode()即可生成啦

以下放个封装好的组件版↓↓↓

<template>
  <div class="codeDom domCenter">
    <canvas ref="canvasCode" width="200px" height="40px"></canvas>
  </div>
</template>
<script>
export default {
  data() {
    return {
      chineseStr: `性亲费间装找北给处原题留业从爱万管曾易发女整热飞尔始单人似进花见望依谈我五立新天是称看据候图被度满相兴通义势她类用形作老几边深注未容告何些主山之黑四都信书房下终工做过领员体空电目条传死于没它报海口月师象拉完像群火强论由虽年里机根尽教共远证式十西次分水起方反许总身却中阳父情其况和政吃今转头六使马着久待英第调子者的设太名系切感如打别公上样所罗首紧让光每品布钱白外成少向微已开德因红故民此闻院王难八离念再`
    };
  },
  props: {
    codeLength: {
      type: Number,
      default: 6
    }
  },
  methods: {
    clearCanvas() { //清除绘制
      let canvas = this.$refs["canvasCode"];
      let canvasCode = canvas.getContext("2d");
      canvasCode.fillStyle = "#FFF";
      canvasCode.fillRect(0, 0, canvas.width, canvas.height);
    },
    drawLine(canvasCode) {
      //绘制线条
      for (let i = 0; i < 20; i++) {
        //绘制背景潦草线条
        canvasCode.beginPath(); //开始一个路径
        canvasCode.moveTo(Math.random() * 200, Math.random() * 40); //设置起点坐标
        canvasCode.lineTo(Math.random() * 200, Math.random() * 40); //设置终点坐标
        canvasCode.strokeStyle = "#27ba5a"; //线条颜色
        canvasCode.stroke(); //开始绘制
      }
    },
    drawText(canvasCode) {
      //绘制验证码
      let codeStr = ""; //验证码内容

      for (let i = 0; i < this.codeLength; i++) {
        //绘制随机汉字
        const x = 20 + i * 20; //x轴位置
        const y = 15 + Math.random() * 10; //y轴位置
        const deg = (180 * Math.random() * Math.PI) / 180 / 2; //文字内容的旋转角度
        const singleWord = this.chineseStr[
          Math.floor(Math.random() * this.chineseStr.length)
        ]; //获取的随机单字
        codeStr += singleWord;
        canvasCode.font = "16px 微软雅黑"; //文字格式
        canvasCode.fillStyle = "red"; //文字颜色
        canvasCode.translate(x, y); //文字所在的位置
        canvasCode.rotate(deg); //文字旋转一哈
        canvasCode.fillText(singleWord, 0, 0); //写入文字
        canvasCode.rotate(-deg); //恢复一下文字旋转度数,不然翻车
        canvasCode.translate(-x, -y); //恢复一下文字所在的位置操作,不然翻车
      }

      return codeStr;
    },
    getCode() {
      this.clearCanvas(); //清除上一波的绘制
      let canvasCode = this.$refs["canvasCode"].getContext("2d");
      this.drawLine(canvasCode); //绘制线条
      let codeStr = this.drawText(canvasCode); // 绘制验证码
      this.$emit("codeCall", codeStr); //将验证码内容返回给父组件
    }
  },
  mounted() {
    this.getCode();
  }
};
</script>
<style lang="scss" scoped>
.codeDom {
  margin-top: 20px;
  height:42px;
  canvas {
    border: 1px solid #4b517a;
  }
}
</style>

接下来到调用↓↓↓

<template>
  <div>
    <codePage
      ref="codePage"
      @codeCall="receiveCode"
      :codeLength="8"
    />
  </div>
</template>
<script>
import codePage from "@/components/codePage.vue";
export default {
  components: {
    codePage
  },
  data() {
    return {
      codeCorrect: "",
    };
  },
  methods: {
    receiveCode(val) { //接收验证码,并赋值
      this.codeCorrect = val;
    }
  },
  mounted() {}
};
</script>
  • 😃
  • 😂
  • 😅
  • 😉
  • 😌
  • 😔
  • 😓
  • 😘
  • 😡
  • 😭
  • 😱
  • 😳
  • 😵
  • 🌚
  • 👍
  • 👎
  • 💪
  • 🌹
  • 💊
  • 🇨🇳
  • 🇺🇸