缘由:之前看哔哩哔哩官网登录的时候有一个拼图验证码,很好奇怎么去实现,然后就想着自己弄一个。先给大家看我的最终效果。后面再一点点拆解代码。
为什么想着写这个功能呢,主要在于拼图验证码在前端这里会比较复杂并且深入。相比文字拼写,12306的图片验证码都没有拼图验证码对前端的要求来的复杂,和难。
我总结下知识点:
1,弹窗功能
2,弹窗基于元素定位
3元素拖动
4,帆布绘图
5,基础逻辑
一、弹窗和弹窗组件
抱歉,这里我偷懒了直接用了elementUI的el-popover组件,所以小伙伴不懂的直接看elementUI官网的说明。
我个人也研究和编写了这块的组件功能(基于波普尔。js)
二、编写基础结构
这块属于html的基础内容,也就标题党了
三、帆布绘制图片
1,帆布绘制外部img图片
代码:
<>之前让mainDom=document.querySelector (“# codeImg”);让bg=mainDom.getContext (2 d);让宽度=mainDom.width;让身高=mainDom.height;让blockDom=document.querySelector (“# sliderBlock”);让块=blockDom.getContext (2 d);//重新赋值,让帆布进行重新绘制 blockDom。身高=身高; mainDom。身高=高度;让imgsrc=https://www.yisu.com/zixun/require(“. ./资产/图片/back.jpg”);让img=document.createElement (img); img.style。objectFit=敖档汀? img。src=https://www.yisu.com/zixun/imgsrc; img。onload=function () { bg。drawImage (img, 0, 0,宽度、高度);块。drawImage (img, 0, 0,宽度、高度); };复制代码这里我绘制了两个画布,因为一个是背景一个是滑块
核心在于
<>之前让mainDom=document.querySelector (“# codeImg”);让imgsrc=https://www.yisu.com/zixun/require(“. ./资产/图片/back.jpg”);让bg=mainDom.getContext (2 d);让img=document.createElement (img); img。onload=function () { bg。drawImage (img, 0, 0,宽度、高度); }; 复制代码2,帆布绘制滑块部分
就是这个图,这个有一些知识点,不难,但是很复杂。
代码部分:
drawBlock (ctx, xy={x: 254 y: 109 r: 9},类型){ 让x=xy.x, y=xy.y, r=xy.r, w=40; 让π=Math.PI;//绘制 ctx.beginPath ();//左 ctx。函数(x, y);//顶部 ctx。弧(x + (w + 5)/2, y, r -π,0,true); ctx。画线(x + w + 5, y);//右 ctx。弧(x + w + 5, y + w/2, r, 1.5 *π,0.5 *π,假); ctx。画线(x + w + 5, y + w);//底部 ctx。弧(x + (w + 5)/2, y + w, r, 0,π,假); ctx。画线(x, y + w); ctx。弧(x, y + w/2 r, 0.5 *π,1.5 *π,true); ctx。画线(x, y);//修饰,没有会看不出效果 ctx。线宽=1; ctx。fillStyle=" rgba (255、255、255、0.5)”; ctx。strokeStyle=" rgba (255、255、255、0.5)”; ctx.stroke (); ctx[型](); ctx。globalCompositeOperation=耙旎颉? }复制代码
解释下:
参数是传入画布对象
x, y轴数据
剪切还是填充的帆布函数(填补,剪辑)
绘制难点:(很重要,不然你没法理解它怎么绘制的)
绘制主要是需要理解这里的绘制是根据你设置一个起始点坐标,然后你绘制第二次的时候线就会连接到第二个点,依次连接最后回到原点就形成一个完整的图形。
用的是电弧参数,主要是看这个图
填充是用于填充绘制的部分,剪辑是裁剪出绘制的部分,利用这个就可以出现一个扣掉的图片和一个裁剪出来的图片。
完成之后就是我的那个函数了。大家可以直接拿去用。
3,让元素跟随鼠标点击之后滑动
这里其实原理非常简单,就是有一个注意点。
原理:
鼠标点击之后记录当前坐标,然后随着(mousemove)滚动的时候修改元素的顶部和左值就行了。
还有一点就是鼠标快速滑动会导致丢失滑动效果,这里需要用文档,不能是元素级别的监听。
元素上面我只需要鉴定按下mousedown
代码:
//鼠标按下拖(e){控制台。日志(“鼠标按下”,e);让dom=e。target;//dom元素 让滑块=document.querySelector (“# sliderBlock”);//滑块dom const downCoordinate={x: e。x, y: e。y};//正确的滑块数据 让checkx=数(this.slider.mx)数(this.slider.bx);//x轴数据 让x=0;const=moveEV=比移动;{ x=moveEV。x - downCoordinate.x;//y=moveEV。y - downCoordinate.y; if (x祝辞=251 | | & lt; x=0)返回false; dom.style。左=x +“px”;//dom.style。顶级=y +“px”; slider.style。左=x +“px”; };const=()=比;{文档。removeEventListener (“mousemove”,移动);文档。removeEventListener (“mouseup”); dom.style。左=" ";控制台。日志(x, checkx);让max=checkx - 5;让min=checkx - 10;//允许正负误差1 如果(max祝辞=x,,x祝辞=min) | | x===checkx) {console.log(“滑动解锁成功”);这一点。谜题=true;这一点。提示="验证成功”; setTimeout(()=比;{这个。可见=false; },500); 其他}{console.log(“拼图位置不正确”);这一点。提示="验证失败,请重试”;这一点。谜题=false;this.canvasInit (); } };文档。addEventListener (“mousemove”,移动);文档。addEventListener (“mouseup”); }复制代码终于实现滑动拼图验证码,vue