js+cavans实现图片滑块验证


Posted in Javascript onSeptember 29, 2020

本文实例为大家分享了js+cavans实现图片滑块验证的具体代码,供大家参考,具体内容如下

js已封装好,拿来即用,兼容pc端和移动端,

效果:

移动端: 

js+cavans实现图片滑块验证

pc端:

js+cavans实现图片滑块验证

原理就不解释了,我之前的博客已经说过,只不过这个版本是结合了canvas实现,又兼容了pc端,直接拿代码就能用了。

代码:html

<!DOCTYPE html>
<html lang="en">
 
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <style>
 * {
 margin: 0;
 padding: 0;
 }
 
 
 .sliderModel {
 position: fixed;
 left: 0;
 top: 0;
 width: 100%;
 height: 100%;
 background: rgba(0, 0, 0, 0.5);
 display: flex;
 justify-content: center;
 align-items: center;
 display: none;
 
 }
 .sliderModel .cont{padding: 20px; width: 280px; background: #fff;border-radius: 6px;margin: 50px auto;}
 .showMessage {
 text-align: center;
 font-size: 14px;
 height: 30px;
 line-height: 30px;
 }
 
 #canvas_wrap{
 width: 280px;
 }
 #canvas_wrap canvas{
 display: block; 
 }
 
 </style>
</head>
 
<body>
 <div class="sliderModel">
 <div class="cont">
 <div id="canvas_wrap"></div>
 <div class="showMessage"></div>
 </div>
 <div id="close">关闭</div>
 </div>
 <div id="open">打开</div>
</body>
<script src="newSlider.js"></script>
<script>
 function showMessage(msg,color){
 var showMessage = document.querySelector('.showMessage');
 showMessage.innerHTML=msg;
 showMessage.style.color=color;
 }
 var obj={
 el:'#canvas_wrap',
 w:280,
 h:150,
 imgArr:['images/sliderz/1.jpg','images/sliderz/2.jpg','images/sliderz/3.jpg','images/sliderz/4.jpg'],
 sliderIcon:'images/sliderz/sangangy.png',
 refresh:function(){
 showMessage('','#333')
 },
 finish:function(e){ 
 e? showMessage('验证成功!','green') : showMessage('验证失败,请重试','red');
 }
 }
 
 
 document.querySelector('#open').onclick=function(){ //打开
 document.querySelector('.sliderModel').style.display="block";
 new window.$newSlider(obj);
 
 }
 
 document.querySelector('#close').onclick=function(){ //关闭
 document.querySelector('.sliderModel').style.display="none";
 }
</script>
 
</html>

newSlider.js:

(function(){
 function slider(params){
 var obj={
 el:params.el,
 w:params.w || 280, //canvas的宽度
 h:params.h || 150, //canvas的高度
 range:params.range || 5, //相差多少像素内触发成功
 imgArr:params.imgArr || [], //图片数组
 sliderW:36, //slider的边长
 sliderIcon:params.sliderIcon || '',
 refresh:params.refresh, //刷新回调
 finish:params.finish , //完成回调
 
 };
 
 //创建canvas的父元素
 var container=document.querySelector(obj.el);
 container.innerHTML='';
 var canvas_wrap=document.createElement('div');
 canvas_wrap.className="canvas_wrap";
 canvas_wrap.style.cssText="position:relative;overflow:hidden;border-radius:4px;width:"+obj.w+"px;height:"+obj.h+"px;background:#fff"
 //创建大小canvas元素
 var bigCanvas=document.createElement('canvas');
 var smartCanvas=bigCanvas.cloneNode(true);
 bigCanvas.width=smartCanvas.width=obj.w;
 bigCanvas.height=smartCanvas.height=obj.h;
 bigCanvas.style.cssText=smartCanvas.style.cssText="position:absolute;left:0;top:0";
 var bcxt=bigCanvas.getContext('2d'),scxt=smartCanvas.getContext('2d'),img=new Image();
 //创建标题和刷新按钮
 var titleDom=document.createElement('div');
 var refreshDom=document.createElement('div');
 titleDom.className="slider_title";
 refreshDom.className="slider_refresh";
 titleDom.style.cssText="position:relative;width:"+obj.w+"+px;height:60px;text-align:center;font-size:18px; line-height:60px";
 refreshDom.style.cssText="position:absolute;top:0;right:14px;font-size:14px;color:green;cursor: pointer";
 titleDom.innerHTML="图形验证";
 refreshDom.innerHTML="刷新";
 
 //创建拖拽区域
 var slider_wrap=document.createElement('div'),slider=document.createElement('div'),sliderCover=document.createElement('div');
 slider_wrap.className="slider_wrap";
 slider.className="canvas_slider";
 sliderCover.className="sliderCover";
 slider_wrap.innerText="拖动左边滑块完成上方拼图";
 slider_wrap.style.cssText="width:"+obj.w+"px;height:30px; border-radius:30px;line-height:30px; position:relative;margin-top:10px;text-align:center;box-shadow: inset 0 0 4px #ccc;font-size: 14px;color:#999";
 slider.style.cssText="cursor: pointer;position: absolute;left: 0;top: 50%;z-index: 2;height: "+obj.sliderW+"px;width: "+obj.sliderW+"px;background:rgb(0, 124, 255) url("+obj.sliderIcon+") no-repeat center;background-size: 60% 60%;border-radius: "+obj.sliderW+"px;line-height:"+obj.sliderW+"px;text-align:center;transform: translateY(-50%);";
 sliderCover.style.cssText="position: absolute;left: 0;top:0;width:0;height:100%;background:#eee;border-radius:30px;"
 
 slider_wrap.appendChild(slider);
 slider_wrap.appendChild(sliderCover);
 canvas_wrap.appendChild(bigCanvas);
 canvas_wrap.appendChild(smartCanvas);
 titleDom.appendChild(refreshDom);
 container.appendChild(titleDom);
 container.appendChild(canvas_wrap);
 container.appendChild(slider_wrap);
 
 
 var canvasCoverL=0,startDownX=0,smartCanvasBL=0,sliderMaxRange=obj.w-obj.sliderW; 
 /*
 canvasCoverL:随机生成占位块canvas的x轴位置
 startDownX://鼠标按下时x轴位置
 smartCanvasBL: 可移动canvas的left初始值
 sliderMaxRange:slider可移动的最大距离
 */
 
 //生成canvas图案
 function creatCanvas(){
 //重置初始值
 canvasCoverL=0;startDownX=0;smartCanvasBL=0; 
 slider.style.left = sliderCover.style.width = 0;
 
 var l= 40, //滑块的正方形边长,不包括小圆点
 r = 10, //小圆点半径
 PI = Math.PI,
 sliderW=l+2*r, //滑块边长
 rand=canvasSize(sliderW,r), //获取随机生成的x,y,left值
 x = canvasCoverL= rand.x, //占位块x轴
 y = rand.y; //占位块y轴
 
 smartCanvasBL=rand.left;
 //先清空画布
 bcxt.clearRect(0, 0, obj.w, obj.h)
 scxt.clearRect(0, 0, obj.w, obj.h)
 smartCanvas.width=obj.w;
 
 var srcIndex=Math.floor(Math.random()*(obj.imgArr.length-1));
 img.src=obj.imgArr[srcIndex];
 draw(scxt,x,y,l,r,PI,'clip');
 draw(bcxt,x,y,l,r,PI,'fill');
 img.onload = function() { //一定要在onload里调用,否则canvas里不能放进图片
 bcxt.drawImage(img,0,0,obj.w,obj.h);
 scxt.drawImage(img,0,0,obj.w,obj.h);
 //裁剪滑块长度
 var ImageData = scxt.getImageData(x, y-2*r, sliderW, sliderW)
 smartCanvas.width = sliderW;
 smartCanvas.style.left=rand.left+"px";
 scxt.putImageData(ImageData, 0, y-2*r)
 } 
 obj.refresh && obj.refresh();
 }
 
 //随机生成canvas滑块和占位块,到左边的距离和到顶部的距离
 function canvasSize(cw,r){
 // cw为占位块和的宽度,r为绘制圆点的半径
 var random =Math.random();
 var x=Math.floor(obj.w/2 + random*(obj.w/2 - cw)); //x为占位块x坐标位置,保证占位块始终在画布的右半区域
 var y=Math.floor(r*2+random*(obj.h - cw - r*2)); //y为占位块y坐标位置,(值至少为小圆半径的2倍才能完全显示,因为绘制的原点是小正方形的左上角)
 var left =Math.floor(random*(obj.w/2 - cw)); //canvas滑块的left值,这里的值范围保证它始终在画布的左半区域
 return {x:x,y:y,left:left}
 }
 
 //绘制canvas滑块和占位块
 function draw(ctx,x,y,l,r,PI,operation) {
 ctx.beginPath()
 ctx.moveTo(x, y)
 ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
 ctx.lineTo(x + l, y)
 ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
 ctx.lineTo(x + l, y + l)
 ctx.lineTo(x, y + l)
 ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
 ctx.lineTo(x, y)
 ctx.lineWidth = 1
 ctx.fillStyle = 'rgba(200, 200, 200, 1)'
 ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
 ctx.stroke()
 ctx[operation]()
 ctx.globalCompositeOperation = 'destination-over'
 }
 
 
 
 
 //滑块被按下
 function moveStart(e){
 var ev = e || window.event;
 startDownX = ev.touches!=undefined? ev.touches[0].clientX : ev.clientX; 
 }
 //滑块移动
 function moveProcess(e){
 var ev = e || window.event,downX = (ev.touches!=undefined)? ev.touches[0].clientX : (startDownX!=0? ev.clientX : 0),range=downX-startDownX;
 console.log(downX)
 var sliderRange= range<=0? 0 : (range<sliderMaxRange ? range : sliderMaxRange);
 slider.style.left=sliderRange+"px";
 sliderCover.style.width=obj.sliderW/2 + sliderRange +"px";
 smartCanvas.style.left=smartCanvasBL+sliderRange+"px";
 }
 
 //停止滑动
 function moveEnd(e){
 var ev = e || window.event;
 ev.touches!=undefined? slider.ontouchmove=null : slider.onmousemove=null;
 var smartCanvasL= parseInt(smartCanvas.style.left);
 if(Math.abs(canvasCoverL - smartCanvasL) < obj.range){
 obj.finish && obj.finish(true);
 }else{
 obj.finish && obj.finish(false);
 var timer = null,step = 10;
 var sliderL = parseInt(slider.style.left)
 timer = setInterval(function () {
  sliderL -= step;
  step += 5;
  if (sliderL <= 0) {
  clearInterval(timer);
  sliderL = 0;
  slider.style.left = sliderCover.style.width = 0;
  smartCanvas.style.left = smartCanvasBL + "px"
  }
  slider.style.left = sliderL + "px";
  sliderCover.style.width = sliderL+obj.sliderW/2 +"px";
  smartCanvas.style.left = sliderL + smartCanvasBL+ "px";
 }, 20)
 }
 
 }
 
 
 //事件调用
 creatCanvas();
 refreshDom.onclick=refreshDom.ontouchstart=creatCanvas;
 slider.ontouchstart=function(){
 moveStart();
 this.ontouchmove=moveProcess;
 this.ontouchend=moveEnd;
 };
 slider.onmousedown=function(){
 moveStart();
 this.onmousemove=moveProcess;
 this.onmouseup=moveEnd;
 };
 
 }
 
 window.$newSlider=slider
})()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 操作单选框,复选框,下拉列表实现代码
Oct 27 Javascript
js获取网页高度(详细整理)
Dec 28 Javascript
Jquery中的层次选择器与find()的区别示例介绍
Feb 20 Javascript
js利用prototype调用Array的slice方法示例
Jun 09 Javascript
JavaScript验证18位身份证号码最后一位正确性的实现代码
Aug 07 Javascript
Javascript非构造函数的继承
Apr 27 Javascript
JavaScript中数组slice和splice的对比小结
Sep 22 Javascript
详解Bootstrap各式各样的按钮(推荐)
Dec 13 Javascript
JavaScript自执行函数和jQuery扩展方法详解
Oct 27 jQuery
ActiveX控件的使用-js实现打印超市小票功能代码详解
Nov 22 Javascript
10个在JavaScript开发中常遇到的BUG
Dec 18 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
Nov 05 Javascript
如何利用JS将手机号中间四位变成*号
Sep 29 #Javascript
原生JavaScript实现刮刮乐
Sep 29 #Javascript
原生JavaScript实现拖动校验功能
Sep 29 #Javascript
使用JavaScript实现贪吃蛇游戏
Sep 29 #Javascript
解决idea开发遇到javascript动态添加html元素时中文乱码的问题
Sep 29 #Javascript
Openlayers3实现车辆轨迹回放功能
Sep 29 #Javascript
vue 验证两次输入的密码是否一致的方法示例
Sep 29 #Javascript
You might like
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
PHP模板引擎Smarty内建函数section,sectionelse用法详解
2016/04/11 PHP
PHP获取用户客户端真实IP的解决方案
2016/10/10 PHP
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
JavaScript高级程序设计 读书笔记之九 本地对象Array
2012/02/27 Javascript
代码获取历史上的今天发生的事
2014/04/11 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
2014/09/22 Javascript
JS实现点击上移下移LI行数据的方法
2015/08/05 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
深入理解jquery中extend的实现
2016/12/22 Javascript
Vue cli构建及项目打包以及出现的问题解决
2018/08/27 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
React 使用recharts实现散点地图的示例代码
2018/12/07 Javascript
Vue.js递归组件实现组织架构树和选人功能
2019/07/04 Javascript
Vue 利用指令实现禁止反复发送请求的两种方法
2019/09/15 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
jQuery实现移动端图片上传预览组件的方法分析
2020/05/01 jQuery
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
2020/09/21 Javascript
基于vuex实现购物车功能
2021/01/10 Vue.js
详解Python2.x中对Unicode编码的使用
2015/04/03 Python
Python爬虫爬取一个网页上的图片地址实例代码
2018/01/16 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
详解Python 调用C# dll库最简方法
2019/06/20 Python
Python bisect模块原理及常见实例
2020/06/17 Python
如何设置PyCharm中的Python代码模版(推荐)
2020/11/20 Python
python 如何引入协程和原理分析
2020/11/30 Python
CSS3中线性颜色渐变的一些实现方法
2015/07/14 HTML / CSS
爱普生美国官网:Epson美国
2018/11/05 全球购物
导游的职业规划书范文
2013/12/27 职场文书
竟聘演讲稿范文
2013/12/31 职场文书
中学生励志演讲稿
2014/04/26 职场文书
群众路线领导对照材料
2014/08/23 职场文书
售房协议书范本2014
2014/10/23 职场文书
关于办理居住证的介绍信模板
2019/11/27 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers