当前位置: 首页 > 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.聚合结果…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...

项目进度管理软件是什么?项目进度管理软件有哪些核心功能?

无论是建筑施工、软件开发&#xff0c;还是市场营销活动&#xff0c;项目往往涉及多个团队、大量资源和严格的时间表。如果没有一个系统化的工具来跟踪和管理这些元素&#xff0c;项目很容易陷入混乱&#xff0c;导致进度延误、成本超支&#xff0c;甚至失败。 项目进度管理软…...

在MobaXterm 打开图形工具firefox

目录 1.安装 X 服务器软件 2.服务器端配置 3.客户端配置 4.安装并打开 Firefox 1.安装 X 服务器软件 Centos系统 # CentOS/RHEL 7 及之前&#xff08;YUM&#xff09; sudo yum install xorg-x11-server-Xorg xorg-x11-xinit xorg-x11-utils mesa-libEGL mesa-libGL mesa-…...