Vue identify generates image verification code

identify is a Vue component that uses canvas to generate graphic verification codes.

Insert picture description here
Create the identify.vue file in the components folder, the code is as follows, change the number of interference lines and interference points, the verification code can be more clear

<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>

The method of use is as follows

<template>
    <div>
        <div class="content">
            <span>验证码:</span>
            <input type="text">
            <div @click="refreshCode">
                <s-identify :identifyCode="identifyCode"></s-identify>
            </div>
        </div>
    </div>
</template>

<script>
	// 引入组件 identify
    import SIdentify from '../components/identify'
    export default {
    
    
        components: {
    
    
        	// 注册组件
            SIdentify
        },
        data() {
    
    
            return {
    
    
                identifyCodes: "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                identifyCode: ""
            }
        },
        mounted() {
    
    
            this.identifyCode = '',
            this.makeCode(this.identifyCodes, 4)
        },
        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)
                    ]
                }
                console.log(this.identifyCode);
            }
        }
    }
</script>

<style scoped>
    .content {
    
    
        display: flex;
        align-items: center;
    }
</style>

Test effect:

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_44640323/article/details/113175212