成都创新互联网站制作重庆分公司

终于实现滑动拼图验证码,vue

缘由:之前看哔哩哔哩官网登录的时候有一个拼图验证码,很好奇怎么去实现。然后就想着自己弄一个。先给大家看我的最终效果。后面再一点点拆解代码。

创新互联公司服务项目包括和政网站建设、和政网站制作、和政网页制作以及和政网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,和政网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到和政省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

终于实现滑动拼图验证码,vue

为什么想着写这个功能呢,主要在于拼图验证码在前端这里会比较复杂并且深入。相比文字拼写,12306的图片验证码都没有拼图验证码对前端的要求来的复杂,和难。

我总结下知识点:

1、弹窗功能

2、弹窗基于元素定位

3、元素拖动

4、canvas绘图

5、基础逻辑

一、弹窗和弹窗组件

抱歉,这里我偷懒了直接用了elementUI的el-popover组件,所以小伙伴不懂的直接看elementUI官网的说明。

我个人也研究和编写了这块的组件功能(基于popper.js)

二、编写基础结构

这块属于html的基础内容,也就标题党了

三、canvas绘制图片

1、canvas绘制外部img图片

代码:

let mainDom = document.querySelector("#codeImg");let bg = mainDom.getContext("2d");let width = mainDom.width;let height = mainDom.height;let blockDom = document.querySelector("#sliderBlock");let block = blockDom.getContext("2d");
//重新赋值,让canvas进行重新绘制
blockDom.height = height;
mainDom.height = height;let imgsrc = require("../assets/images/back.jpg");let img = document.createElement("img");
img.style.objectFit = "scale-down";
img.src = imgsrc;
img.onload = function() {
 bg.drawImage(img, 0, 0, width, height); block.drawImage(img, 0, 0, width, height);
};复制代码

这里我绘制了两个canvas,因为一个是背景一个是滑块

核心在于

let mainDom = document.querySelector("#codeImg");let imgsrc = require("../assets/images/back.jpg");let bg = mainDom.getContext("2d");let img = document.createElement("img");
img.onload = function() {
 bg.drawImage(img, 0, 0, width, height);
};
复制代码

2、canvas绘制滑块部分

就是这个图,这个有一些知识点,不难,但是很复杂。

终于实现滑动拼图验证码,vue

代码部分:

drawBlock(ctx, xy = { x: 254, y: 109, r: 9 }, type) {
 let x = xy.x,
 y = xy.y,
 r = xy.r,
 w = 40;
 let PI = Math.PI; //绘制
 ctx.beginPath(); //left
 ctx.moveTo(x, y); //top
 ctx.arc(x + (w + 5) / 2, y, r, -PI, 0, true);
 ctx.lineTo(x + w + 5, y); //right
 ctx.arc(x + w + 5, y + w / 2, r, 1.5 * PI, 0.5 * PI, false);
 ctx.lineTo(x + w + 5, y + w); //bottom
 ctx.arc(x + (w + 5) / 2, y + w, r, 0, PI, false);
 ctx.lineTo(x, y + w);
 ctx.arc(x, y + w / 2, r, 0.5 * PI, 1.5 * PI, true);
 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[type]();
 ctx.globalCompositeOperation = "xor";
}复制代码

解释下:

参数是传入canvas对象

x,y轴数据

剪切还是填充的canvas函数(fill,clip)

绘制难点:(很重要,不然你没法理解它怎么绘制的)

绘制主要是需要理解这里的绘制是根据你设置一个起始点坐标,然后你绘制第二次的时候线就会连接到第二个点,依次连接最后回到原点就形成一个完整的图形。

终于实现滑动拼图验证码,vue

用的是arc参数,主要是看这个图

fill是用于填充绘制的部分,clip是裁剪出绘制的部分,利用这个就可以出现一个扣掉的图片和一个裁剪出来的图片。

完成之后就是我的那个函数了。大家可以直接拿去用。

3、让元素跟随鼠标点击之后滑动

这里其实原理非常简单,就是有一个注意点。

原理:

鼠标点击之后记录当前坐标,然后随着(mousemove)滚动的时候修改元素的left和top值就行了。

还有一点就是鼠标快速滑动会导致丢失滑动效果,这里需要用document,不能是元素级别的监听。

元素上面我只需要鉴定按下mousedown

代码:

//鼠标按下drag(e) { console.log("鼠标按下", e); let dom = e.target; //dom元素
 let slider = document.querySelector("#sliderBlock"); //滑块dom
 const downCoordinate = { x: e.x, y: e.y }; //正确的滑块数据
 let checkx = Number(this.slider.mx) - Number(this.slider.bx); //x轴数据
 let x = 0; const move = moveEV => {
 x = moveEV.x - downCoordinate.x; //y = moveEV.y - downCoordinate.y;
 if (x >= 251 || x <= 0) return false;
 dom.style.left = x + "px"; //dom.style.top = y + "px";
 slider.style.left = x + "px";
 }; const up = () => { document.removeEventListener("mousemove", move); document.removeEventListener("mouseup", up);
 dom.style.left = ""; console.log(x, checkx); let max = checkx - 5; let min = checkx - 10; //允许正负误差1
 if ((max >= x && x >= min) || x === checkx) { console.log("滑动解锁成功"); this.puzzle = true; this.tips = "验证成功";
 setTimeout(() => { this.visible = false;
 }, 500);
 } else { console.log("拼图位置不正确"); this.tips = "验证失败,请重试"; this.puzzle = false; this.canvasInit();
 }
 }; document.addEventListener("mousemove", move); document.addEventListener("mouseup", up);
}复制代码

4、总结

核心点比较多,写过之后发现不难,关键在于去写

个人该页面git地址:https://github.com/ht-sauce/dream

该页面处于项目的

终于实现滑动拼图验证码,vue

路由访问为:http://localhost:8080/consumer

5、完整的页面代码

最后

喜欢的可以点个关注吗,小可乐也不容易呢

终于实现滑动拼图验证码,vue


文章题目:终于实现滑动拼图验证码,vue
文章分享:http://cxhlcq.com/article/jscpig.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部