本文实例为大家分享了js+cavans实现图片滑块验证的具体代码,供大家参考,具体内容如下
js已封装好,拿来即用,兼容pc端和移动端,
效果:
移动端:
pc端:
原理就不解释了,我之前的博客已经说过,只不过这个版本是结合了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="/UploadFiles/2021-04-02/newSlider.js">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"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"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 })()以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
风云阁资源网 Design By www.bgabc.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
风云阁资源网 Design By www.bgabc.com
暂无评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
2024年11月17日
2024年11月17日
- 中国武警男声合唱团《辉煌之声1天路》[DTS-WAV分轨]
- 紫薇《旧曲新韵》[320K/MP3][175.29MB]
- 紫薇《旧曲新韵》[FLAC/分轨][550.18MB]
- 周深《反深代词》[先听版][320K/MP3][72.71MB]
- 李佳薇.2024-会发光的【黑籁音乐】【FLAC分轨】
- 后弦.2012-很有爱【天浩盛世】【WAV+CUE】
- 林俊吉.2012-将你惜命命【美华】【WAV+CUE】
- 晓雅《分享》DTS-WAV
- 黑鸭子2008-飞歌[首版][WAV+CUE]
- 黄乙玲1989-水泼落地难收回[日本天龙版][WAV+CUE]
- 周深《反深代词》[先听版][FLAC/分轨][310.97MB]
- 姜育恒1984《什么时候·串起又散落》台湾复刻版[WAV+CUE][1G]
- 那英《如今》引进版[WAV+CUE][1G]
- 蔡幸娟.1991-真的让我爱你吗【飞碟】【WAV+CUE】
- 群星.2024-好团圆电视剧原声带【TME】【FLAC分轨】