精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

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

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

[[358782]]

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

 

你將收獲

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

設計思路

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

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

效果預覽

圖片

實現思路

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

  1. function Gcode(el, option) { 
  2.     this.el = typeof el === 'string' ? document.querySelector(el) : el; 
  3.     this.option = option
  4.     this.init(); 

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

1.繪制畫布

  1. Gcode.prototype = { 
  2.     constructor: Gcode, 
  3.     init: function() { 
  4.         if(this.el.getContext) { 
  5.             isSupportCanvas = true
  6.             var ctx = this.el.getContext('2d'), 
  7.             // 設置畫布寬高 
  8.             cw = this.el.width = this.option.width || 200, 
  9.             ch = this.el.height = this.option.height || 40; 
  10.         } 
  11.     } 

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

2.繪制干擾線

  1. // 畫干擾線 
  2. drawLine: function(ctx, lineNum, maxW, maxH) { 
  3.     ctx.clearRect(0, 0, maxW, maxH); 
  4.     for(var i=0; i < lineNum; i++) { 
  5.         var dx1 = Math.random()* maxW, 
  6.             dy1 = Math.random()* maxH, 
  7.             dx2 = Math.random()* maxW, 
  8.             dy2 = Math.random()* maxH; 
  9.         ctx.strokeStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'
  10.         ctx.beginPath(); 
  11.         ctx.moveTo(dx1, dy1); 
  12.         ctx.lineTo(dx2, dy2); 
  13.         ctx.stroke(); 
  14.     } 

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

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

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

  1. // 生成唯一文字 
  2. generateUniqueText: function(source, hasList, limit) { 
  3.     var text = source[Math.floor(Math.random()*limit)]; 
  4.     if(hasList.indexOf(text) > -1) { 
  5.         return this.generateUniqueText(source, hasList, limit) 
  6.     }else { 
  7.         return text 
  8.     }   
  9. // 生成指定個數的隨機文字 
  10. randomText: function(len) { 
  11.     var source = ['a''b''c''d''e'
  12.     'f''g''h''i''j',  
  13.     'k''l''m''o''p'
  14.     'q''r''s''t''u'
  15.     'v''w''x''y''z']; 
  16.     var result = []; 
  17.     var sourceLen = source.length; 
  18.     for(var i=0; i< len; i++) { 
  19.         var text = this.generateUniqueText(source, result, sourceLen); 
  20.         result.push(text) 
  21.     } 
  22.     return result.join(''

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

4.用canvas繪制文字

  1. // 畫文字 
  2. drawText: function(ctx, text, maxH) { 
  3.     var len = text.length; 
  4.     for(var i=0; i < len; i++) { 
  5.         var dx = 30 * Math.random() + 30* i, 
  6.             dy = Math.random()* 5 + maxH/2; 
  7.         ctx.fillStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'
  8.         ctx.font = '30px Helvetica'
  9.         ctx.textBaseline = 'middle'
  10.         ctx.fillText(text[i], dx, dy); 
  11.     } 
  12. }, 

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

5.初始化和canvas點擊事件

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

  1. init: function() { 
  2.     if(this.el.getContext) { 
  3.         isSupportCanvas = true
  4.         var ctx = this.el.getContext('2d'), 
  5.         // 設置畫布寬高 
  6.         cw = this.el.width = this.option.width || 200, 
  7.         ch = this.el.height = this.option.height || 40, 
  8.         textLen = this.option.textLen || 4, 
  9.         lineNum = this.option.lineNum || 4; 
  10.         var text = this.randomText(textLen); 
  11.  
  12.         this.onClick(ctx, textLen, lineNum, cw, ch); 
  13.         this.drawLine(ctx, lineNum, cw, ch); 
  14.         this.drawText(ctx, text, ch); 
  15.     } 

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

  1. onClick: function(ctx, textLen, lineNum, cw, ch) { 
  2.     var _ = this; 
  3.     this.el.addEventListener('click'function(){ 
  4.         text = _.randomText(textLen); 
  5.         _.drawLine(ctx, lineNum, cw, ch); 
  6.         _.drawText(ctx, text, ch); 
  7.     }, false

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

  1. new Gcode('#canvas_code', { 
  2.         lineNum: 6,  // 可選 
  3.         textLen: 4,  // 可選 
  4.         width: 200,  // 可選 
  5.         height: 50   // 可選 
  6.     }) 

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

  1. // canvas繪制圖形驗證碼 
  2.     (function(){ 
  3.         function Gcode(el, option) { 
  4.             this.el = typeof el === 'string' ? document.querySelector(el) : el; 
  5.             this.option = option
  6.             this.init(); 
  7.         } 
  8.         Gcode.prototype = { 
  9.             constructor: Gcode, 
  10.             init: function() { 
  11.                 if(this.el.getContext) { 
  12.                     isSupportCanvas = true
  13.                     var ctx = this.el.getContext('2d'), 
  14.                     // 設置畫布寬高 
  15.                     cw = this.el.width = this.option.width || 200, 
  16.                     ch = this.el.height = this.option.height || 40, 
  17.                     textLen = this.option.textLen || 4, 
  18.                     lineNum = this.option.lineNum || 4; 
  19.                     var text = this.randomText(textLen); 
  20.          
  21.                     this.onClick(ctx, textLen, lineNum, cw, ch); 
  22.                     this.drawLine(ctx, lineNum, cw, ch); 
  23.                     this.drawText(ctx, text, ch); 
  24.                 } 
  25.             }, 
  26.             onClick: function(ctx, textLen, lineNum, cw, ch) { 
  27.                 var _ = this; 
  28.                 this.el.addEventListener('click'function(){ 
  29.                     text = _.randomText(textLen); 
  30.                     _.drawLine(ctx, lineNum, cw, ch); 
  31.                     _.drawText(ctx, text, ch); 
  32.                 }, false
  33.             }, 
  34.             // 畫干擾線 
  35.             drawLine: function(ctx, lineNum, maxW, maxH) { 
  36.                 ctx.clearRect(0, 0, maxW, maxH); 
  37.                 for(var i=0; i < lineNum; i++) { 
  38.                     var dx1 = Math.random()* maxW, 
  39.                         dy1 = Math.random()* maxH, 
  40.                         dx2 = Math.random()* maxW, 
  41.                         dy2 = Math.random()* maxH; 
  42.                     ctx.strokeStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'
  43.                     ctx.beginPath(); 
  44.                     ctx.moveTo(dx1, dy1); 
  45.                     ctx.lineTo(dx2, dy2); 
  46.                     ctx.stroke(); 
  47.                 } 
  48.             }, 
  49.             // 畫文字 
  50.             drawText: function(ctx, text, maxH) { 
  51.                 var len = text.length; 
  52.                 for(var i=0; i < len; i++) { 
  53.                     var dx = 30 * Math.random() + 30* i, 
  54.                         dy = Math.random()* 5 + maxH/2; 
  55.                     ctx.fillStyle = 'rgb(' + 255*Math.random() + ',' + 255*Math.random() + ',' + 255*Math.random() + ')'
  56.                     ctx.font = '30px Helvetica'
  57.                     ctx.textBaseline = 'middle'
  58.                     ctx.fillText(text[i], dx, dy); 
  59.                 } 
  60.             }, 
  61.             // 生成指定個數的隨機文字 
  62.             randomText: function(len) { 
  63.                 var source = ['a''b''c''d''e'
  64.                 'f''g''h''i''j',  
  65.                 'k''l''m''o''p'
  66.                 'q''r''s''t''u'
  67.                 'v''w''x''y''z']; 
  68.                 var result = []; 
  69.                 var sourceLen = source.length; 
  70.                 for(var i=0; i< len; i++) { 
  71.                     var text = this.generateUniqueText(source, result, sourceLen); 
  72.                     result.push(text) 
  73.                 } 
  74.                 return result.join(''
  75.             }, 
  76.             // 生成唯一文字 
  77.             generateUniqueText: function(source, hasList, limit) { 
  78.                 var text = source[Math.floor(Math.random()*limit)]; 
  79.                 if(hasList.indexOf(text) > -1) { 
  80.                     return this.generateUniqueText(source, hasList, limit) 
  81.                 }else { 
  82.                     return text 
  83.                 }   
  84.             } 
  85.         } 
  86.         new Gcode('#canvas_code', { 
  87.             lineNum: 6 
  88.         }) 
  89.     })(); 

 

責任編輯:姜華 來源: 趣談前端
相關推薦

2009-11-23 16:59:23

PHP圖形驗證碼

2020-01-06 13:11:30

技術工具

2021-08-11 06:57:17

驗證碼圖片顯示

2015-09-21 15:31:05

php實現驗證碼

2024-12-09 10:21:30

2023-09-22 11:51:13

PythonFlask

2015-12-11 09:54:47

2018-09-18 10:11:21

前端vue.jsjavascript

2009-12-16 15:46:41

Ruby on rai

2013-06-19 10:19:59

2024-07-30 08:59:22

2009-06-26 15:17:27

jQuery

2020-09-29 06:43:12

Java

2020-11-16 07:28:53

驗證碼

2009-02-09 14:17:36

2009-08-11 14:05:28

JSP驗證碼

2022-02-11 07:10:15

驗證碼

2021-01-19 10:29:34

短信驗證碼密碼

2015-03-23 17:58:04

驗證碼倒計時并行
點贊
收藏

51CTO技術棧公眾號

色爽爽爽爽爽爽爽爽| 国产精品久久久久国产a级| 成人做爰www看视频软件| 草草在线视频| 国产精品少妇自拍| 99精彩视频在线观看免费| 黄色大片网站在线观看| 久久国产成人午夜av影院宅| 亚洲国产成人精品电影| 国产一二三四在线视频| 欧美aaa免费| 日本一区二区三区视频视频| 成人蜜桃视频| 亚洲自拍第二页| 亚洲乱码久久| 久久视频精品在线| 无码一区二区三区在线| 天堂精品在线视频| 精品视频1区2区| 欧美视频免费看欧美视频| 亚洲区一区二区三| 一区二区三区四区视频免费观看| 色综合色狠狠综合色| 日本一道在线观看| 97超碰人人在线| 99re在线视频这里只有精品| 亚洲一区二区三区视频播放| 欧美超碰在线观看| 99精品热6080yy久久| 久久精品欧美视频| 国产jjizz一区二区三区视频| av综合网页| 欧美一区二区三区四区在线观看 | 成年人在线观看网站| 懂色av一区二区三区免费观看| 国产精品一区=区| 成人午夜视频在线播放| 影音先锋在线一区| 欧美日韩福利视频| 婷婷久久综合网| 成人久久综合| 一区二区三区回区在观看免费视频| 亚洲av无码一区二区三区观看| 欧美日韩黄网站| 制服丝袜亚洲精品中文字幕| 182午夜在线观看| 日本肉肉一区| 欧美视频精品在线观看| 成人免费xxxxx在线视频| 三级成人黄色影院| 91国模大尺度私拍在线视频| 成年人网站大全| a一区二区三区| 一本大道久久精品懂色aⅴ| 欧美亚洲一二三区| 成人影院av| 色婷婷亚洲精品| 成人在线免费播放视频| 欧美日韩激情电影| 欧美视频你懂的| 亚洲免费av一区| 亚洲国产综合在线观看| 在线综合亚洲欧美在线视频| 在线观看中文av| 在线综合色站| 亚洲国产精久久久久久| 泷泽萝拉在线播放| 欧美精选一区二区三区| 最近2019年中文视频免费在线观看 | 中文字幕精品无| 视频一区免费在线观看| 国产精品吹潮在线观看| 国产又大又黑又粗| 丁香亚洲综合激情啪啪综合| 久久久精品动漫| 国产香蕉视频在线看| 国产精品家庭影院| 国产精品va在线观看无码| av日韩中文| 在线精品国精品国产尤物884a| 天天操,天天操| 亚洲成人偷拍| 亚洲欧美一区二区三区情侣bbw | 国产欧美一区二| 欧美成年网站| 亚洲九九九在线观看| 美国精品一区二区| 欧美特黄视频| 国产精品国语对白| 国产丰满美女做爰| 久久久综合视频| 中文字幕日韩一区二区三区| а_天堂中文在线| 欧美无乱码久久久免费午夜一区| 日韩av福利在线观看| 欧美自拍视频| 超碰91人人草人人干| 波多野结衣国产| 精彩视频一区二区三区| 九九九九九九精品| 国产精品实拍| 色婷婷亚洲精品| 波多野结衣中文字幕在线播放| 欧美理论电影在线精品| 北条麻妃99精品青青久久| 91午夜视频在线观看| 男女性色大片免费观看一区二区| 鬼打鬼之黄金道士1992林正英| 秋霞av在线| 亚洲永久精品大片| 色悠悠久久综合网| 美女午夜精品| 美女性感视频久久久| 国产精品视频一区在线观看| 高清国产午夜精品久久久久久| 神马一区二区影院| 精品丝袜在线| 欧美大片一区二区三区| 亚洲精品天堂网| 久久久成人网| 久久国产精品-国产精品| а√中文在线8| 欧美视频你懂的| 99久久人妻无码精品系列| 亚洲看片一区| 999国内精品视频在线| 最新国产在线观看| 色噜噜狠狠一区二区三区果冻| 国产69视频在线观看| 91精品天堂福利在线观看| 国产精品男人的天堂| 欧美视频综合| 天天色天天操综合| 少妇献身老头系列| 欧美天天视频| 91精品国产一区二区三区动漫 | 日本不卡免费高清视频| 天天躁日日躁狠狠躁喷水| 夜夜亚洲天天久久| 女人扒开腿免费视频app| 天天操夜夜操国产精品| 国产欧美一区二区白浆黑人| 成人影院免费观看| 在线观看精品一区| 一级肉体全黄裸片| 蜜乳av一区二区| 亚洲精品永久www嫩草| 久久免费资源| 日韩中文字幕在线精品| 一起草av在线| 1024成人网| 中文字幕在线视频一区二区| 亚洲精品极品少妇16p| 成人黄色免费网站在线观看| 麻豆免费在线视频| 日韩亚洲欧美一区| 久久99久久久| 94色蜜桃网一区二区三区| 男人日女人下面视频| 在线一级成人| 国产精品视频不卡| 里番在线观看网站| 欧美成人激情免费网| 日本天堂网在线观看| 99久久精品国产毛片| 97视频在线免费播放| 黑丝美女一区二区| 国产在线视频2019最新视频| 永久免费网站在线| 精品亚洲国产视频| 中文字幕乱码中文字幕| 亚洲欧美区自拍先锋| 亚洲一区二区三区四区av| 国产一区二区精品| 亚洲欧洲日韩综合二区| 精品中文在线| 欧美一级片久久久久久久| 第一页在线观看| 日韩精品一区二区三区四区 | 日韩经典av| 亚洲女成人图区| 国产孕妇孕交大片孕| 亚洲一区免费视频| 法国空姐电影在线观看| 狠狠色丁香婷婷综合久久片| 国产a级片网站| 欧美理论视频| 国产精品制服诱惑| 狂野欧美性猛交xxxx| 午夜精品久久久久久久99热浪潮 | 久久91亚洲人成电影网站| 手机看片一区二区| 欧美久久高跟鞋激| 男女啊啊啊视频| 日韩理论片中文av| 无码人妻精品一区二区三应用大全| 美腿丝袜亚洲一区| 欧美综合在线播放| 国产精品久久久久久麻豆一区软件 | 成人精品毛片| 国产精品一区专区欧美日韩| www视频在线观看| 日韩一级黄色av| 日本一二三区在线视频| 欧美一区午夜精品| av首页在线观看| 亚洲一区二区三区爽爽爽爽爽| 亚洲ⅴ国产v天堂a无码二区| 成人小视频在线| 国产又黄又猛的视频| 亚洲一区日韩| 久青草视频在线播放| 日韩中文首页| 日本亚洲自拍| 欧美日韩导航| av一区二区三区免费| 99久久精品一区二区成人| 91av在线免费观看| 午夜av在线播放| 北条麻妃在线一区二区| 97在线观看免费观看高清| 亚洲精品视频久久| 涩涩视频免费看| 日韩欧美国产一区在线观看| 一级久久久久久久| 在线观看日韩一区| 亚洲天堂五月天| 欧美日韩午夜剧场| 国产成人无码精品久在线观看| 亚洲精品国产精品乱码不99| 一区二区三区影视| 国产精品福利一区二区三区| 99久久久无码国产精品衣服| 久久蜜桃香蕉精品一区二区三区| 国产精品伦子伦| 99久久精品情趣| 国产一级黄色录像| 成人自拍视频在线观看| 国产chinesehd精品露脸| 国产真实乱对白精彩久久| 欧美精品网站| 国产视频欧美视频| 日韩一级片免费观看| 精品国产露脸精彩对白| 亚洲AV无码精品色毛片浪潮| 欧美刺激脚交jootjob| 国产高清不卡视频| 欧美一区二区三区人| 国产三区在线播放| 日韩三级视频在线观看| 亚洲精品.www| 亚洲国产毛片完整版| 五月婷婷六月丁香综合| 亚洲精品天天看| 欧美孕妇孕交| 尤物精品国产第一福利三区 | 永久免费精品影视网站| 二人午夜免费观看在线视频| 影音先锋欧美精品| 老司机在线视频二区| 色在人av网站天堂精品| heyzo一区| 日韩免费av一区二区| 成人四虎影院| 99一区二区| 亚洲色图美女| 亚洲狠狠婷婷综合久久久| 永久亚洲成a人片777777| 999一区二区三区| 久久精选视频| 拔插拔插华人永久免费| 懂色一区二区三区免费观看 | 色狠狠久久av综合| 日本中文不卡| 911久久香蕉国产线看观看| 国产精品视频一二三四区| 一本久道综合久久精品| 日日噜噜噜噜久久久精品毛片| 国内精品第一页| 2一3sex性hd| 欧美经典一区二区| 久久无码精品丰满人妻| 在线精品视频一区二区| www.精品久久| 国产亚洲精品高潮| 在线看福利影| 国产福利精品视频| 欧美一级大片在线视频| 欧美精品一区二区三区在线四季| 久久高清免费| 国产99久久九九精品无码| 麻豆91在线看| 日韩aaaaa| 1024精品合集| 久久久久久久久久成人| 日韩一区二区三区在线视频| 美国成人毛片| 欧美疯狂做受xxxx高潮| 成人午夜在线| 激情五月综合色婷婷一区二区| 欧美国产一级| 蜜臀av午夜一区二区三区| 国产成人在线免费| 女人黄色一级片| 精品久久久视频| a级片在线免费看| 中文字幕欧美在线| 午夜影院一区| 国产成人亚洲欧美| 手机在线一区二区三区| 欧洲av无码放荡人妇网站| 国产成人免费视频一区| 99久久99久久精品免费看小说.| 午夜精品影院在线观看| 国产精品久久久久久无人区| 亚洲日韩中文字幕在线播放| 好久没做在线观看| 亚洲最大成人网色| 久久中文亚洲字幕| 欧美一级裸体视频| 久久午夜电影网| 亚洲日本韩国在线| 精品成人在线观看| 亚洲电影视频在线| 91啪国产在线| 91麻豆精品国产91久久久平台| wwwwww.色| 久久久久久久网| 超碰中文字幕在线| 亚洲国产欧美一区| h片精品在线观看| 国产99午夜精品一区二区三区 | 欧美福利在线播放网址导航| 中文字幕精品在线播放| 精品一区二区三区在线播放视频 | 国产精品免费在线免费| 国产一区不卡| 激情六月丁香婷婷| 久久久国产午夜精品| 麻豆精品久久久久久久99蜜桃| 亚洲第一天堂av| 91超碰免费在线| 国偷自产av一区二区三区小尤奈| 今天的高清视频免费播放成人| 日韩精品xxx| 亚洲一二三区视频在线观看| 亚洲精品成av人片天堂无码| 欧美高跟鞋交xxxxxhd| 91成人午夜| 国产69精品久久久久久久| 99热99精品| 六月丁香婷婷综合| 亚洲人成网在线播放| 偷拍视频一区二区三区| 亚洲黄色一区二区三区| 国内精品写真在线观看| 久久网免费视频| 日韩精品在线私人| 亚洲天堂一区二区| 制服诱惑一区| 国产精品亚洲第一区在线暖暖韩国| 久久老司机精品视频| 日韩电影在线观看中文字幕| 吞精囗交69激情欧美| 在线免费观看成人网| 国产精品白丝jk黑袜喷水| 国产网址在线观看| 亚洲色图国产精品| 国产精品99久久免费| 亚洲精品蜜桃久久久久久| 久久久噜噜噜久久中文字幕色伊伊| 人妻中文字幕一区二区三区| 久久精品视频网站| 久久99精品久久久久久欧洲站| 91黄色小网站| 国产精品国产三级国产普通话三级| 国产99视频在线| 欧美在线性视频| 亚洲香蕉av| 国产精品300页| 欧美人体做爰大胆视频| 丁香花在线电影| 日韩国产欧美精品| 国产毛片精品一区| 国产美女激情视频| 久久影院在线观看| 天堂网av成人| 国产资源中文字幕| 同产精品九九九| 超碰在线免费播放| 久久精品国产精品国产精品污| 美女精品一区二区| 日韩xxxxxxxxx| 日韩有码在线播放| 牛牛影视一区二区三区免费看| 天天色综合社区| 精品日韩美女的视频高清| 免费网站看v片在线a| 精品欧美一区二区精品久久| 精品一区二区三区久久|