极简原生js图形验证码

前天接到需求要在老项目登陆界面加上验证码功能,因为是内部项目且无需短信验证环节,那就直接用原生js写一个简单的图形验证码。

示例:

思路:此处假设验证码为4位随机数值,数值刷新满足两个条件①页面新进/刷新。②点击图片刷新。(实际情况下还要考虑登录出错刷新,此处只做样式不写进去) 实现过程为1.先写一个canvas标签做绘图容器。 → 2.将拿到的值绘制到容器中并写好样式。 → 3.点击刷新重新绘制。

写一个canvas标签当容器

html 复制代码
<canvas
    style="width: 100px;border: 2px solid rgb(60, 137, 209);background-image: url('https://gd-hbimg.huaban.com/aa3c7f23dfdc7b2d317aa4b77bd6c7b8469564d2dfa8b-Btd5c6_fw658webp');"
    id="captchaCanvas"></canvas>

并设置容器宽高背景颜色或图片等样式

写一个数值绘制到canvas的方法

js 复制代码
//text为传递的数值
function generateCaptcha(text, callback) {
      var canvas = document.getElementById('captchaCanvas');
      var ctx = canvas.getContext('2d');
      // 设置字体及大小
      ctx.font = '100px Comic Sans MS';
      // 设置字体颜色
      ctx.fillStyle = 'rgb(' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ')';
      // 调整文字图形位置
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      // 调整阴影范围
      ctx.shadowBlur = Math.random() * 20;
      // 调整阴影颜色
      ctx.shadowColor = 'rgb(' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ')';
      // 调整阴影位置(偏移量)
      ctx.shadowOffsetX = Math.random() * 10;
      ctx.shadowOffsetY = Math.random() * 10;
      // 绘制文字图形及其偏移量
      ctx.fillText(text, 25, 35);
      // 绘制文字边框及其偏移量
      ctx.strokeText(text, Math.random() * 35, Math.random() * 45);

      var imgDataUrl = canvas.toDataURL();
      callback(imgDataUrl);

    }

拿到数值调用绘制方法

此处为样式示例,因此数值我用4位随机数表示,实际情况为你从后端取得的值,并依靠这个值在后端判断验证码是否一致。

js 复制代码
// 调用函数生成验证码并显示在页面上  
    generateCaptcha(Math.floor(Math.random() * 9000) + 1000, function (imgDataUrl) { });

监听标签点击实现点击刷新

此处要注意一定要先清空canvas中已绘制图像再渲染新数值,因此直接将清除范围设置较大。

js 复制代码
 // 监听点击更新验证码
    document.getElementById("captchaCanvas").addEventListener("click", function (event) {
      // 清空画布
      document.getElementById("captchaCanvas").getContext("2d").clearRect(0, 0, 9999, 9999);
      // 调用函数生成验证码并显示在页面上  
      generateCaptcha(Math.floor(Math.random() * 9000) + 1000, function (imgDataUrl) { });
    })

最后实现效果:

完整代码演示

html 复制代码
<!DOCTYPE html>
<html>

<head>
  <title>String to Captcha</title>
</head>

<body>
  <canvas
    style="width: 100px;border: 2px solid rgb(60, 137, 209);background-image: url('https://gd-hbimg.huaban.com/aa3c7f23dfdc7b2d317aa4b77bd6c7b8469564d2dfa8b-Btd5c6_fw658webp');"
    id="captchaCanvas"></canvas>


  <script>
    // 监听点击更新验证码
    document.getElementById("captchaCanvas").addEventListener("click", function (event) {
      // 清空画布
      document.getElementById("captchaCanvas").getContext("2d").clearRect(0, 0, 9999, 9999);
      // 调用函数生成验证码并显示在页面上  
      generateCaptcha(Math.floor(Math.random() * 9000) + 1000, function (imgDataUrl) { });
    })

    function generateCaptcha(text, callback) {
      var canvas = document.getElementById('captchaCanvas');
      var ctx = canvas.getContext('2d');
      // 设置字体及大小
      ctx.font = '100px Comic Sans MS';
      // 设置字体颜色
      ctx.fillStyle = 'rgb(' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ')';
      // 调整文字图形位置
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      // 调整阴影范围
      ctx.shadowBlur = Math.random() * 20;
      // 调整阴影颜色
      ctx.shadowColor = 'rgb(' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ')';
      // 调整阴影位置(偏移量)
      ctx.shadowOffsetX = Math.random() * 10;
      ctx.shadowOffsetY = Math.random() * 10;
      // 绘制文字图形及其偏移量
      ctx.fillText(text, 25, 35);
      // 绘制文字边框及其偏移量
      ctx.strokeText(text, Math.random() * 35, Math.random() * 45);

      var imgDataUrl = canvas.toDataURL();
      callback(imgDataUrl);

    }

    // 调用函数生成验证码并显示在页面上  
    generateCaptcha(Math.floor(Math.random() * 9000) + 1000, function (imgDataUrl) { });
  </script>
</body>

</html>
相关推荐
还是大剑师兰特24 分钟前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
一只小白菜~31 分钟前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding35 分钟前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT40 分钟前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓40 分钟前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
发现你走远了40 分钟前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
吖秧吖1 小时前
three.js 杂记
开发语言·前端·javascript
前端小超超1 小时前
vue3 ts项目结合vant4 复选框+气泡弹框实现一个类似Select样式的下拉选择功能
前端·javascript·vue.js
大叔是90后大叔1 小时前
vue3中查找字典列表中某个元素的值
前端·javascript·vue.js
IT大玩客1 小时前
JS如何获取MQTT的主题
开发语言·javascript·ecmascript