验证码组件封装

本文介绍了如何使用JavaScript和CanvasAPI实现一个可定制格式(纯数字、纯字母或数字+字母)的验证码组件,包括验证码的动态生成、尺寸调整以及事件触发功能。
摘要由CSDN通过智能技术生成

功能实现

1、实现了基于canvas验证码组件的封装

2、提供纯数字,纯字母,数字+字母三种模式

3、点击验证码更新数据

源代码

<template>
    <canvas id="s-canvas" @click="drawPic" :width="contentWidth" :height="contentHeight"></canvas>
</template>
<script>
export default {
    name: 'SIdentify',
    props: {
        type: {
            type: String,
            default: 'number'
        },
        fontSizeMin: { // 字体最小值
            type: Number,
            default: 25
        },
        fontSizeMax: { // 字体最大值
            type: Number,
            default: 35
        },
        backgroundColorMin: { // 验证码图片背景色最小值
            type: Number,
            default: 200
        },
        backgroundColorMax: { // 验证码图片背景色最大值
            type: Number,
            default: 220
        },
        dotColorMin: { // 背景干扰点最小值
            type: Number,
            default: 60
        },
        dotColorMax: { // 背景干扰点最大值
            type: Number,
            default: 120
        },
        contentWidth: { // 容器宽度
            type: Number,
            default: 90
        },
        contentHeight: { // 容器高度
            type: Number,
            default: 38
        }
    },
    data() {
        return {
            identifyCode: ''
        }
    },
    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 = '#e6ecfd'
            ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)

            this.identifyCode = this.generateRandomString(4)
            this.$emit("change", this.identifyCode)
            // 绘制文字
            for (let i = 0; i < this.identifyCode.length; i++) {
                this.drawText(ctx, this.identifyCode[i], i)
            }
            this.drawLine(ctx)
            this.drawDot(ctx)
        },
        generateRandomString(length) {
            // const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let characters;
            if (this.type === 'number') {
                characters = "0123456789"
            } else if (this.type === "letter") {
                characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
            } else if (this.type === "alphanumeric") {
                characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
            }
            let result = '';

            for (let i = 0; i < length; i++) {
                const randomIndex = Math.floor(Math.random() * characters.length);
                result += characters.charAt(randomIndex);
            }

            return result;
        },
        drawText(ctx, txt, i) {
            ctx.fillStyle = this.randomColor(50, 160) // 随机生成字体颜色
            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(-30, 30)
            // 修改坐标原点和旋转角度
            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 < 4; i++) {
                ctx.strokeStyle = this.randomColor(100, 200)
                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 < 30; 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()
            }
        }
    },
    mounted() {
        this.drawPic()
    }
}
</script>
   

配置项

参数名称

参数类型

参数说明

默认值

可选参数

type

String

验证码的格式

number

number/letter/alphanumeric

fontSizeMin

Number

字体最小值

25

fontSizeMax

Number

字体最大值

35

backgroundColorMin

Number

验证码图片背景色最小值

200

backgroundColorMax

Number

验证码图片背景色最大值

220

dotColorMin

Number

背景干扰点最小值

60

dotColorMax

Number

背景干扰点最大值

120

contentWidth

Number

容器宽度

90

contentHeight

Number

容器高度

38

事件

事件名称

事件说明

类型

事件参数

change

当绑定值变化时触发的事件

Function

value为验证码的值

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值