当前位置: 首页 > news >正文

滑动验证码-elementui实现

使用elementui框架实现

html代码
<div class="button-center"><el-popoverplacement="top":width="imgWidth"title="安全验证"trigger="manual"v-model="popoverVisible"@hide="popoverHide"@show="popoverShow"><div class="z-popover"><!--    滑块图片        --><canvas id="sliderImg"></canvas><!--背景图片--><canvas id="backgroundImg"></canvas><el-slider v-model="sliderValue" :show-tooltip="showTooltip" @input="sliderInput"@change="sliderChange" v-mousedown="sliderDown"></el-slider><el-divider></el-divider><i class="el-icon-circle-close z-el-popover-size" @click="popoverVisible = false"title="关闭"></i><i class="el-icon-refresh z-el-popover-size" @click="popoverShow"title="更换验证码"></i><span class="z-slider-result">{{sliderResult}}</span></div><el-button slot="reference" type="primary" @click="login()" :disabled="isDisabled"class="login-register-button-width">登录</el-button></el-popover></div>
主要代码:
function SliderImg(width, height, r, w) {this.width = width;this.height = height;this.r = r;this.w = w;// 使用双缓冲区去闪烁let getBufferCanvas = () => {// 创建隐藏Canvaslet buffer = document.createElement('canvas');buffer.width = this.width;buffer.height = this.height;buffer.ctx = buffer.getContext('2d');buffer.ctx.setTransform(1, 0, 0, 1, 0, 0);return buffer;}let init = () => {if (!this.backgroundImg || !this.sliderImg) {this.backgroundImg = document.getElementById("backgroundImg")this.backgroundImg.width = this.width;this.backgroundImg.height = this.height;this.backgroundImg.ctx = this.backgroundImg.getContext('2d');this.sliderImg = document.getElementById("sliderImg")this.sliderImg.width = this.width;this.sliderImg.height = this.height;this.sliderImg.ctx = this.sliderImg.getContext('2d');}this.sliderWidth = 2 * (this.r + this.w);$("#sliderImg").css('position', 'absolute').css("left", "0px");this.buffer1 = this.buffer1 == null ? getBufferCanvas() : this.buffer1;this.buffer2 = this.buffer2 == null ? getBufferCanvas() : this.buffer2;this.pos = getPos();}this.drawImg = function (src) {init();let img = new Image();img.src = src;img.onload = () => {drawBgBlock(img, this.buffer1.ctx);drawSiBlock(img, this.buffer2.ctx);}}let drawBgBlock = (img, ctx) => {ctx.clearRect(0, 0, this.width, this.height);ctx.drawImage(img, 0, 0, this.width, this.height);// 绘制滑块的形状drawBlock(ctx);ctx.fill();// 将缓冲区内容绘制到实际的画布中this.backgroundImg.ctx.clearRect(0, 0, this.width, this.height);this.backgroundImg.ctx.drawImage(this.buffer1, 0, 0, this.width, this.height);}let drawSiBlock = (img, ctx) => {ctx.clearRect(0, 0, this.width, this.height);ctx.drawImage(img, 0, 0, this.width, this.height);// 创建一个临时画布画一个圆, 然后将图片绘制上去, 形成一个滑块let tempCanvas = getBufferCanvas();tempCanvas.ctx.translate(-this.pos.siOffset, 0);drawBlock(tempCanvas.ctx);tempCanvas.ctx.clip();tempCanvas.ctx.drawImage(this.buffer2, 0, 0);// 将缓冲区内容绘制到实际的画布中this.sliderImg.ctx.clearRect(0, 0, this.width, this.height);this.sliderImg.ctx.drawImage(tempCanvas, 0, 0, this.width, this.height);}/*** 绘制缺口** @param ctx*/let drawBlock = (ctx) => {let x = this.pos.x, y = this.pos.y, r = this.pos.r, w = this.pos.w;ctx.beginPath();ctx.moveTo(x, y);// left// ctx.lineTo(x, y + w); 第一条直线可以省略, 下同理ctx.arc(x, y + w + r, r, -0.5 * Math.PI, 0.5 * Math.PI, false);ctx.lineTo(x, y + 2 * (w + r));// bottomctx.arc(x + w + r, y + 2 * (w + r), r, Math.PI, 0, true);ctx.lineTo(x + 2 * (w + r), y + 2 * (w + r));// rightctx.arc(x + 2 * (w + r), y + w + r, r, 0.5 * Math.PI, -0.5 * Math.PI, true);ctx.lineTo(x + 2 * (w + r), y);// topctx.arc(x + w + r, y, r, 0, Math.PI, false);ctx.lineTo(x, y);// 添加可见的效果ctx.lineWidth = 1;ctx.fillStyle = "rgba(255, 255, 255, 0.5)";ctx.strokeStyle = "rgba(255, 255, 255, 0.5)";ctx.stroke();// 和已有的图形进行异或操作ctx.globalCompositeOperation = "xor";}/*** 获取缺口坐标*/let getPos = () => {// 背景缺口的x轴坐标let x = getRandomNum(this.width / 2 + this.sliderWidth, this.width - 1.5 * this.sliderWidth);// 滑块的偏移量let siOffset = getRandomNum(0.45 * this.width, 0.55 * this.width);// 相同的y轴高度let y = getRandomNum(0.5 * this.sliderWidth, this.height - 1.5 * this.sliderWidth);return {x: x,y: y,r: this.r,w: this.w,siOffset: siOffset}}/*** 获取随机数** @param min* @param max* @returns {number}*/let getRandomNum = (min, max) => {return Math.floor(Math.random() * (max - min + 1) + min);}
}
事件方法
// 控制滑块移动
sliderInput(value) {if (this.sliderImg == null) {return;}// 移动的距离let moveLength = value * (this.imgWidth / 100)let start = this.sliderImg.pos.x - this.sliderImg.pos.siOffset;// 控制最大位置if (start + moveLength >= this.imgWidth) {this.sliderValue = value;} else {$("#sliderImg").css("left", moveLength);}
},// 鼠标按下时, 记录当下时间sliderDown() {this.startTime = new Date().getTime();},// 是否成功的判断sliderChange(value) {// 移动的距离let moveLength = value * (this.imgWidth / 100) - this.sliderImg.sliderWidth / 3// 偏移量let offset = this.sliderImg.pos.siOffset;// 允许的误差let mis = 5;// 成功的判断if (Math.abs(moveLength - offset) < mis) {let time = ((new Date().getTime() - this.startTime) / 1000.0).toFixed(2);switch (true) {case (time > 0 && time <= 1): {this.sliderResult = "只用了" + time + "s,快如闪电!"break;}case (time > 1 && time <= 2): {this.sliderResult = "用了" + time + "s,还不错!"break;}default: {this.sliderResult = "居然使用了" + time + "s,果然持久!"}}$(".z-slider-result").removeClass("z-slider-result-error").addClass("z-slider-result-success");// 后续成功的处理setTimeout(() => {this.loginForm.sliderCode = this.getSliderResult(time);}, 500);} else {this.sliderResult = "验证失败!"$(".z-slider-result").removeClass("z-slider-result-success").addClass("z-slider-result-error");this.popoverShow();}},
相关变量
// 以下时滑动图片验证码相关
sliderValue: 0, // 滑块的值
sliderResult: "", // 验证结果
showTooltip: false, // 隐藏tooltip
imgSrc: "/imgs/test2.png", // 图片的src
popoverVisible: false, // 验证框的显示和隐藏
imgWidth: 300, // 验证码图片的宽度
imgHeight: 120,  // 验证码图片的高度
sliderImg: null, // 滑动图片验证码对象
startTime: 0, // 按下滑块的时间
使用示例:
if (this.sliderImg == null) {this.sliderImg = new SliderImg(this.imgWidth, this.imgHeight, 5, 10);
}
this.sliderImg.drawImg(this.imgSrc);
效果图

在这里插入图片描述

相关文章:

滑动验证码-elementui实现

使用elementui框架实现 html代码 <div class"button-center"><el-popoverplacement"top":width"imgWidth"title"安全验证"trigger"manual"v-model"popoverVisible"hide"popoverHide"show&quo…...

ubuntu 20.04 安装 高版本cuda 11.7 和 cudnn最新版

一、安装显卡驱动 参考另一篇文章&#xff1a;Ubuntu20.04安装Nvidia显卡驱动教程_ytusdc的博客-CSDN博客 二、安装CUDA 英伟达官网&#xff08;最新版&#xff09;&#xff1a;CUDA Toolkit 12.2 Update 1 Downloads | NVIDIA Developer CUDA历史版本下载地址&#xff1a;C…...

svg图片如何渲染到页面,以及svg文件的上传

svg图片渲染到页面的几种方式 背景&#x1f7e1;require.context获取目录下的所有文件&#x1f7e1;方式1: 直接在html中渲染&#x1f7e1;方式: 发起ajax请求&#xff0c;获取SVG文件 背景 需要实现从本地目录下去获取所有的svg图标进行预览&#xff0c;将选中的图片显示在另…...

GPT-LLM-Trainer:如何使用自己的数据轻松快速地微调和训练LLM

一、前言 想要轻松快速地使用您自己的数据微调和培训大型语言模型&#xff08;LLM&#xff09;&#xff1f;我们知道训练大型语言模型具有挑战性并需要耗费大量计算资源&#xff0c;包括收集和优化数据集、确定合适的模型及编写训练代码等。今天我们将介绍一种实验性新方法&am…...

深入理解ForkJoin

任务类型 线程池执行的任务可以分为两种&#xff1a;CPU密集型任务和IO密集型任务。在实际的业务场景中&#xff0c;我们需要根据任务的类型来选择对应的策略&#xff0c;最终达到充分并合理地使用CPU和内存等资源&#xff0c;最大限度地提高程序性能的目的。 CPU密集型任务 …...

Spring5学习笔记—AOP编程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Spring专栏 ✨特色专栏&#xff1a; M…...

适用于 Docker 用户的 kubectl

适用于 Docker 用户的 kubectl 你可以使用 Kubernetes 命令行工具 kubectl 与 API 服务器进行交互。如果你熟悉 Docker 命令行工具&#xff0c; 则使用 kubectl 非常简单。但是&#xff0c;Docker 命令和 kubectl 命令之间有一些区别。以下显示了 Docker 子命令&#xff0c; 并…...

网络安全设备篇——加密机

加密机是一种专门用于数据加密和解密的网络安全设备。它通过使用密码学算法对数据进行加密&#xff0c;从而保护数据的机密性和完整性。加密机通常被用于保护敏感数据&#xff0c;如金融信息、个人身份信息等。 加密机的主要功能包括&#xff1a; 数据加密&#xff1a;加密机使…...

Rust 基础入门 —— 2.3.所有权和借用

Rust 的最主要光芒&#xff1a; 内存安全 。 实现方式&#xff1a; 所有权系统。 写在前面的序言 因为我们这里实际讲述的内容是关于 内存安全的&#xff0c;所以我们最好先复习一下内存的知识。 然后我们&#xff0c;需要理解的就只有所有权概念&#xff0c;以及为了开发便…...

Node.js-Express框架基本使用

Express介绍 Express是基于 node.js 的web应用开发框架&#xff0c;是一个封装好的工具包&#xff0c;便于开发web应用&#xff08;HTTP服务&#xff09; Express基本使用 // 1.安装 npm i express // 2.导入 express 模块 const express require("express"); // 3…...

阿里云通用算力型u1云服务器CPU性能详细说明

​阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xff…...

设计模式之创建者模式

文章目录 一、介绍二、应用三、案例1. 麦当劳11随心配2. 代码演示3. 演示结果 四、优缺点五、送给读者 一、介绍 建造者模式(Builder Pattern)属于创建型设计模式&#xff0c;很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说&…...

Java之包,权限修饰符,final关键字详解

包 2.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术&#xff0c;不同的技术类放在不同的包下&#xff0c;方便管理和维护。 在IDEA项目中&#xff0c;建包的操作如下&#xff1a; 包名的命名规范&#xff1a; 路径名.路径名.xxx.xxx // 例如&#xff…...

“深入解析JVM:Java虚拟机内部原理揭秘“

标题&#xff1a;深入解析JVM&#xff1a;Java虚拟机内部原理揭秘 摘要&#xff1a;本文将深入探讨Java虚拟机&#xff08;JVM&#xff09;的内部原理&#xff0c;包括JVM的架构、运行时数据区域、垃圾回收机制以及即时编译器等重要组成部分。通过对JVM内部原理的解析&#xf…...

Mac下Jmeter安装及基本使用

本篇文章只是简单的介绍下Jmeter的下载安装和最基本使用 1、初识Jmeter 前一段时间客户端app自测的过程中&#xff0c;有偶现请求某个接口返回数据为空的问题&#xff0c;领导让我循环100次请求这个接口&#xff0c;看看有没有结果为空的问题。听同事说有Jmeter的专业测试工具…...

云计算与边缘计算:加速数字化转型的关键驱动力

云计算和边缘计算技术正以惊人的速度改变着企业的业务和基础架构。这些先进的技术为企业带来了灵活性、可扩展性和成本效益的优势&#xff0c;重新定义了业务运作的方式。 云计算是通过互联网将计算资源提供给用户的一种服务模式。通过云计算&#xff0c;企业可以将应用程序、…...

TheGem主题 - 创意多用途和高性能WooCommerce WordPress主题/网站

TheGem主题概述 – 适合所有人的TheGem 作为设计元素、样式和功能的终极 Web 构建工具箱而设计和开发&#xff0c;TheGem主题将帮助您在几分钟内构建一个令人印象深刻的高性能网站&#xff0c;而无需触及一行代码。不要在编码上浪费时间&#xff0c;探索你的创造力&#xff01…...

Pytorch-day10-模型部署推理-checkpoint

模型部署&推理 模型部署模型推理 我们会将PyTorch训练好的模型转换为ONNX 格式&#xff0c;然后使用ONNX Runtime运行它进行推理 1、ONNX ONNX( Open Neural Network Exchange) 是 Facebook (现Meta) 和微软在2017年共同发布的&#xff0c;用于标准描述计算图的一种格式…...

vue使用websocket

建立websocket.js // 信息提示 import { Message } from element-ui // 引入用户id import { getTenantId, getAccessToken } from /utils/auth// websocket地址 var url ws://192.168.2.20:48081/websocket/message // websocket实例 var ws // 重连定时器实例 var tt // w…...

jmeter入门:接口压力测试全解析

一.对接口压力测试 1.配置 1.添加线程组&#xff08;参数上文有解释 这里不介绍&#xff09; 2.添加取样器 不用解释一看就知道填什么。。。 3.添加头信息&#xff08;否则请求头对不上&#xff09; 也不用解释。。。 4.配置监听器 可以尝试使用这几个监听器。 2.聚合结果…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...