日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Canvas入門實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)圖形驗(yàn)證碼

 本文主要介紹用canvas實(shí)現(xiàn)圖形驗(yàn)證碼的一些思路以及如何用javascript面向?qū)ο蟮姆绞礁押玫膶?shí)現(xiàn)canvas的功能,關(guān)于canvas的一些基本使用方法和API我整理了一個(gè)思維導(dǎo)圖,大家感興趣的可以參考學(xué)習(xí)。

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),西夏企業(yè)網(wǎng)站建設(shè),西夏品牌網(wǎng)站建設(shè),網(wǎng)站定制,西夏網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,西夏網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

 

你將收獲

  • 閉包的使用
  • canvas常用api的使用
  • javascript面向?qū)ο蟮膶?shí)現(xiàn)方式
  • 實(shí)現(xiàn)一個(gè)canvas的圖形驗(yàn)證碼的一般思路和常用算法

設(shè)計(jì)思路

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

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

效果預(yù)覽

實(shí)現(xiàn)思路

我將按照上文中的設(shè)計(jì)思路的步驟一步步實(shí)現(xiàn),首先我們先定義一個(gè)es5類:

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

其中init是用來初始化用的,參數(shù)el代表需要掛載的元素或元素id,option為傳入的可選項(xiàng),稍后會在代碼中體現(xiàn),通常這也是面向?qū)ο蟮某S锰茁贰?/p>

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.             // 設(shè)置畫布寬高
  8.             cw = this.el.width = this.option.width || 200,
  9.             ch = this.el.height = this.option.height || 40;
  10.         }
  11.     }
  12. }

這里我們在初始化方法中先定義一個(gè)canvas畫布,寬高為用戶自定義的寬高,默認(rèn)為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.     }
  15. }

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

3.生成隨機(jī)不重復(fù)的n個(gè)字符

我們通過遞歸實(shí)現(xià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. // 生成指定個(gè)數(shù)的隨機(jī)文字
  11. randomText: function(len) {
  12.     var source = ['a', 'b', 'c', 'd', 'e',
  13.     'f', 'g', 'h', 'i', 'j', 
  14.     'k', 'l', 'm', 'o', 'p',
  15.     'q', 'r', 's', 't', 'u',
  16.     'v', 'w', 'x', 'y', 'z'];
  17.     var result = [];
  18.     var sourceLen = source.length;
  19.     for(var i=0; i< len; i++) {
  20.         var text = this.generateUniqueText(source, result, sourceLen);
  21.         result.push(text)
  22.     }
  23.     return result.join('')
  24. }

我們通過定義一個(gè)字母表,傳入生成的隨機(jī)字母的個(gè)數(shù),配合generateUniqueText來實(shí)現(xiàn)生成唯一不重復(fù)的n個(gè)隨機(jī)字符。當(dāng)然筆者認(rèn)為這個(gè)方法并不優(yōu)雅,你也可以使用uuid的方式或者更好的方式,歡迎隨時(shí)和筆者交流。

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. },

這里和上文畫線實(shí)現(xiàn)類似。就不做過多介紹了。

5.初始化和canvas點(diǎn)擊事件

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

 
 
 
 
  1. init: function() {
  2.     if(this.el.getContext) {
  3.         isSupportCanvas = true;
  4.         var ctx = this.el.getContext('2d'),
  5.         // 設(shè)置畫布寬高
  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.         this.onClick(ctx, textLen, lineNum, cw, ch);
  12.         this.drawLine(ctx, lineNum, cw, ch);
  13.         this.drawText(ctx, text, ch);
  14.     }
  15. }

點(diǎn)擊事件主要是為了用戶點(diǎn)擊可以切換驗(yàn)證碼:

 
 
 
 
  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)
  8. }

到此,一個(gè)完整的驗(yàn)證碼組件實(shí)現(xiàn)完成,怎么用呢?如下:

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

完整代碼如下,歡迎學(xué)習(xí)交流:

 
 
 
 
  1. // canvas繪制圖形驗(yàn)證碼
  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.                     // 設(shè)置畫布寬高
  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.             // 生成指定個(gè)數(shù)的隨機(jī)文字
  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.     })();

標(biāo)題名稱:Canvas入門實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)圖形驗(yàn)證碼
轉(zhuǎn)載來于:http://m.5511xx.com/article/dhjjosd.html