一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - Canvas入門實戰之實現一個圖形驗證碼

Canvas入門實戰之實現一個圖形驗證碼

2020-12-20 23:50趣談前端徐小夕 JavaScript

本文主要介紹用canvas實現圖形驗證碼的一些思路以及如何用javascript面向對象的方式更友好的實現canvas的功能,關于canvas的一些基本使用方法和API我整理了一個思維導圖,大家感興趣的可以參考學習。

 本文主要介紹用canvas實現圖形驗證碼的一些思路以及如何用javascript面向對象的方式更友好的實現canvas的功能,關于canvas的一些基本使用方法和API我整理了一個思維導圖,大家感興趣的可以參考學習。

Canvas入門實戰之實現一個圖形驗證碼

你將收獲

  • 閉包的使用
  • canvas常用api的使用
  • javascript面向對象的實現方式
  • 實現一個canvas的圖形驗證碼的一般思路和常用算法

設計思路

  1. 用canvas生成畫布
  2. 用canvas畫干擾線或躁點
  3. 生成隨機不重復的n的字母
  4. 用canvas繪制文字
  5. 初始化和canvas點擊事件
  6. 組件化封裝

文末將附上組件封裝的源碼,歡迎大家隨時溝通交流。關于項目的打包,我將使用自己基于gulp4搭建的9012教你如何使用gulp4開發項目腳手架。

效果預覽

Canvas入門實戰之實現一個圖形驗證碼

實現思路

我將按照上文中的設計思路的步驟一步步實現,首先我們先定義一個es5類:

function Gcode(el, option) { 

    this.el = typeof el === 'string' ? document.querySelector(el) : el; 

    this.option = option

    this.init(); 

其中init是用來初始化用的,參數el代表需要掛載的元素或元素id,option為傳入的可選項,稍后會在代碼中體現,通常這也是面向對象的常用套路。

1.繪制畫布

Gcode.prototype = { 

    constructor: Gcode, 

    init: function() { 

        if(this.el.getContext) { 

            isSupportCanvas = true

            var ctx = this.el.getContext('2d'), 

            // 設置畫布寬高 

            cw = this.el.width = this.option.width || 200, 

            ch = this.el.height = this.option.height || 40; 

        } 

    } 

這里我們在初始化方法中先定義一個canvas畫布,寬高為用戶自定義的寬高,默認為200*40。

2.繪制干擾線

// 畫干擾線 

drawLine: function(ctx, lineNum, maxW, maxH) { 

    ctx.clearRect(0, 0, maxW, maxH); 

    for(var i=0; i < lineNum; i++) { 

        var dx1 = Math.random()* maxW, 

            dy1 = Math.random()* maxH, 

            dx2 = Math.random()* maxW, 

            dy2 = Math.random()* maxH; 

        ctx.strokeStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'

        ctx.beginPath(); 

        ctx.moveTo(dx1, dy1); 

        ctx.lineTo(dx2, dy2); 

        ctx.stroke(); 

    } 

這里我們對類Gcode定義原型方法drawLine,然后通過for循環繪制隨機位置的線條,為了讓canvas每次點擊能清空之前的干擾線,我們使用clearRect來清除畫布。

3.生成隨機不重復的n個字符

我們通過遞歸實現,如下==:

// 生成唯一文字 

generateUniqueText: function(source, hasList, limit) { 

    var text = source[Math.floor(Math.random()*limit)]; 

    if(hasList.indexOf(text) > -1) { 

        return this.generateUniqueText(source, hasList, limit) 

    }else { 

        return text 

    }   

// 生成指定個數的隨機文字 

randomText: function(len) { 

    var source = ['a''b''c''d''e'

    'f''g''h''i''j',  

    'k''l''m''o''p'

    'q''r''s''t''u'

    'v''w''x''y''z']; 

    var result = []; 

    var sourceLen = source.length; 

    for(var i=0; i< len; i++) { 

        var text = this.generateUniqueText(source, result, sourceLen); 

        result.push(text) 

    } 

    return result.join(''

我們通過定義一個字母表,傳入生成的隨機字母的個數,配合generateUniqueText來實現生成唯一不重復的n個隨機字符。當然筆者認為這個方法并不優雅,你也可以使用uuid的方式或者更好的方式,歡迎隨時和筆者交流。

4.用canvas繪制文字

// 畫文字 

drawText: function(ctx, text, maxH) { 

    var len = text.length; 

    for(var i=0; i < len; i++) { 

        var dx = 30 * Math.random() + 30* i, 

            dy = Math.random()* 5 + maxH/2; 

        ctx.fillStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'

        ctx.font = '30px Helvetica'

        ctx.textBaseline = 'middle'

        ctx.fillText(text[i], dx, dy); 

    } 

}, 

這里和上文畫線實現類似。就不做過多介紹了。

5.初始化和canvas點擊事件

接下來我們看看完整的初始化代碼:

init: function() { 

    if(this.el.getContext) { 

        isSupportCanvas = true

        var ctx = this.el.getContext('2d'), 

        // 設置畫布寬高 

        cw = this.el.width = this.option.width || 200, 

        ch = this.el.height = this.option.height || 40, 

        textLen = this.option.textLen || 4, 

        lineNum = this.option.lineNum || 4; 

        var text = this.randomText(textLen); 

 

        this.onClick(ctx, textLen, lineNum, cw, ch); 

        this.drawLine(ctx, lineNum, cw, ch); 

        this.drawText(ctx, text, ch); 

    } 

點擊事件主要是為了用戶點擊可以切換驗證碼:

onClick: function(ctx, textLen, lineNum, cw, ch) { 

    var _ = this; 

    this.el.addEventListener('click'function(){ 

        text = _.randomText(textLen); 

        _.drawLine(ctx, lineNum, cw, ch); 

        _.drawText(ctx, text, ch); 

    }, false

到此,一個完整的驗證碼組件實現完成,怎么用呢?如下:

new Gcode('#canvas_code', { 

        lineNum: 6,  // 可選 

        textLen: 4,  // 可選 

        width: 200,  // 可選 

        height: 50   // 可選 

    }) 

完整代碼如下,歡迎學習交流:

// canvas繪制圖形驗證碼 

    (function(){ 

        function Gcode(el, option) { 

            this.el = typeof el === 'string' ? document.querySelector(el) : el; 

            this.option = option

            this.init(); 

        } 

        Gcode.prototype = { 

            constructor: Gcode, 

            init: function() { 

                if(this.el.getContext) { 

                    isSupportCanvas = true

                    var ctx = this.el.getContext('2d'), 

                    // 設置畫布寬高 

                    cw = this.el.width = this.option.width || 200, 

                    ch = this.el.height = this.option.height || 40, 

                    textLen = this.option.textLen || 4, 

                    lineNum = this.option.lineNum || 4; 

                    var text = this.randomText(textLen); 

         

                    this.onClick(ctx, textLen, lineNum, cw, ch); 

                    this.drawLine(ctx, lineNum, cw, ch); 

                    this.drawText(ctx, text, ch); 

                } 

            }, 

            onClick: function(ctx, textLen, lineNum, cw, ch) { 

                var _ = this; 

                this.el.addEventListener('click'function(){ 

                    text = _.randomText(textLen); 

                    _.drawLine(ctx, lineNum, cw, ch); 

                    _.drawText(ctx, text, ch); 

                }, false

            }, 

            // 畫干擾線 

            drawLine: function(ctx, lineNum, maxW, maxH) { 

                ctx.clearRect(0, 0, maxW, maxH); 

                for(var i=0; i < lineNum; i++) { 

                    var dx1 = Math.random()* maxW, 

                        dy1 = Math.random()* maxH, 

                        dx2 = Math.random()* maxW, 

                        dy2 = Math.random()* maxH; 

                    ctx.strokeStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'

                    ctx.beginPath(); 

                    ctx.moveTo(dx1, dy1); 

                    ctx.lineTo(dx2, dy2); 

                    ctx.stroke(); 

                } 

            }, 

            // 畫文字 

            drawText: function(ctx, text, maxH) { 

                var len = text.length; 

                for(var i=0; i < len; i++) { 

                    var dx = 30 * Math.random() + 30* i, 

                        dy = Math.random()* 5 + maxH/2; 

                    ctx.fillStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'

                    ctx.font = '30px Helvetica'

                    ctx.textBaseline = 'middle'

                    ctx.fillText(text[i], dx, dy); 

                } 

            }, 

            // 生成指定個數的隨機文字 

            randomText: function(len) { 

                var source = ['a''b''c''d''e'

                'f''g''h''i''j',  

                'k''l''m''o''p'

                'q''r''s''t''u'

                'v''w''x''y''z']; 

                var result = []; 

                var sourceLen = source.length; 

                for(var i=0; i< len; i++) { 

                    var text = this.generateUniqueText(source, result, sourceLen); 

                    result.push(text) 

                } 

                return result.join(''

            }, 

            // 生成唯一文字 

            generateUniqueText: function(source, hasList, limit) { 

                var text = source[Math.floor(Math.random()*limit)]; 

                if(hasList.indexOf(text) > -1) { 

                    return this.generateUniqueText(source, hasList, limit) 

                }else { 

                    return text 

                }   

            } 

        } 

        new Gcode('#canvas_code', { 

            lineNum: 6 

        }) 

    })(); 

Canvas入門實戰之實現一個圖形驗證碼

原文地址:https://mp.weixin.qq.com/s/KRDmD5RhYtaaGxykCt6jbQ

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲美女爱爱 | 调教催眠改造np总攻 | 国产成人免费在线观看 | 亚洲精品91大神在线观看 | 亚洲日本免费 | 91看片淫黄大片.在线天堂 | 99re8在这里只有精品2 | 美女毛片老太婆bbb80岁 | 国产成人愉拍精品 | 青苹果乐园影院在线播放 | 小黄鸭YELLOWDUCK7596 | 欧美日韩在线一区 | 黄在线观看www免费看 | 四虎最新紧急更新地址 | 色猪视频 | 亚洲国产在线2o20 | 亚洲国产99在线精品一区二区 | 国产高清一区二区三区免费视频 | 国产免费午夜高清 | 欧美a在线| 18日本xxxxxxⅹxx96 | 久久se视频精品视频在线 | 窝窝午夜理伦影院 | 91极品女神久色在线播放 | 18free性欧美另类hd | 久久受www免费人成_看片中文 | 亚洲狼人综合干 | 美女撒尿毛片免费看 | 欧美成人福利 | 青青自拍视频 | 性绞姿始动作动态图 | 啊好大好粗 | 91免费永久国产在线观看 | 午夜无码国产理论在线 | 美女的隐私无遮挡的网页 | 久久国产精品福利影集 | 男人懂得网站 | 国产成人高清精品免费观看 | 91免费播放| 18岁的老处女 | 91sao国产在线观看 |