关于canvas:手把手写个Canvas验证码组件并且与Vue解耦

1次阅读

共计 2198 个字符,预计需要花费 6 分钟才能阅读完成。

明天下班摸鱼,咱们一起来写一个利用 canvas 画布纯前端实现验证码性能。
开始之前咱们先撸一撸开发的流程,先干什么再干什么,把思路撸分明了,干什么都容易。

  1. 当然必须先有一个 canvas 画布
  2. 接着再整几个数字 + 英文下来

咱们先来个空标签,先占个位,当前这里就会有一个 canvas。

<span id="verify"></span>

并且咱们定义了一个 id 为 verify。
接下开始整 canavs 了,咱们须要把 canvas 变到 span 外面。
没有 canvas,就创立一个。

const node = document.getElementById('verify')
const canvas = document.createElement('canvas');
node.appendChild(canvas)
canvas.width = 120
canvas.height = 60

并且咱们棘手把它塞进了 span 外面。到这里咱们的小指标第一步曾经实现了。接下去再整几个数字 + 英文下来就完事了。
要在 canvas 上整点货色,当然先要拿到 canvas。

const ctx = canvas.getContext('2d');

而后咱们间接进入小指标的第二步。

ctx.fillText('jsx123', 0, 0);

到这里预计有人要喷我了,你 TM 整的什么玩意儿。
验证码怎么是写死的,不应该是随机的吗。
是的,没错。
上面咱们就来实现小指标中的细节。
咱们须要失去一个随机的数字 + 字母组合,字母大小写也是随机的。
先定义一段字符串。

const str = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789'

到这里咱们只须要随机选取字符串中的字符即可。咱们封装一个办法,来返回指定长度的随机字符串。

function getString(length) {
  let str = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789'
  let string = ''
  for (let i = 0; i < length; i++) {string += str[Math.floor(Math.random() * str.length)]
  }
  return string
}

控制台跑一下,是咱们想要的后果,改一下咱们的代码。

ctx.fillText(getString(6), 0, 0);

这样咱们每次刷新,呈现的验证码都是随机的。
然而验证码的色彩不是随机的,而且验证码排列的形式也不是咱们想要的。
咱们心愿验证码的每个字符的色彩都是随机的,而且每个字符须要带点旋转,以进步机器辨认的难度。

// 生成随机色
 function randomColor() {return `#${((Math.random() * (0xFFFFFF).toString(10)).toString(16)).slice(-6)}`
  }

不晓得怎么随机生成 16 进制色彩的,能够间接百度。或者应用随机获取 0 -255 整数的办法取得 rgb 色彩。
这里咱们须要遍历验证码的每一个字符。

// 生成指定范畴内的随机数
function getRandom(min, max) {return Math.floor(Math.random() * (max - min + 1)) + min
}

let code = getString(6)
for (let i = 0; i < code.length; i++) {ctx.save()
    ctx.strokeStyle = randomColor()
    ctx.rotate(getRandom(-30, 30) * Math.PI / 180)
    ctx.fillText(code[i], 0, 0);
    ctx.restore()}

到这一步咱们一次性实现了验证码字符的色彩随机和角度旋转。
为了烦扰机器辨认,咱们须要增加杂线。

ctx.lineWidth = getRandom(1, 3)
ctx.strokeStyle = randomColor()
ctx.beginPath();
ctx.moveTo(start, end);
ctx.lineTo(start, end);
ctx.stroke();

这里咱们还是须要应用 for 循环顺次画出多条杂线,能够看到 lineWidth 以及 strokeStyle 线宽度和填充色都应用了随机值,特地留神的是线的终点和起点start,end, 仍旧传入随机值。比方:

const start = getRandom(-width / 2, width * 1.5)
const end = getRandom(-height / 2, height * 1.5)

到这里一个字符随机,字符色彩随机,字符角度随机,背景杂线随机的验证码曾经实现了。

在一些细节中咱们能够做出相应的扭转,如此一来验证码的性能将不断完善,比方背景能够应用不同透明度的随机色字符作为烦扰,或者是弧线,或者是虚线。
同时验证码还能够做加减乘的计算,咱们只须要随机取 2 个数字和 1 个运算符号,将他们画在 canvas 上。

因为篇幅的问题,具体的实现流程不在这里论述了,具体的代码我已上传 github。

https://github.com/humanlegacy/canvas-verify-code

或者 npm 装置查看源码

# 装置依赖
npm i canvas-verify-code

文章写完了,我该溜了溜了,不足之处大家评论区留言探讨呀

正文完
 0