vue+elementui实现拖住滑块拼图验证
2022-04-17 19:48:47 来源:易采站长站 作者:
vue拖住滑块拼图验证,以下是cavas直接写的滑块拼图验证码,直接复制引用即可

<template><div id="puzzle" ref="puzzle" style="display:inline-block;"><!-- :style="'padding:' + 16*scale + 'px ' + 16*scale + 'px ' + 28*scale + 'px;border-radius:'+16*scale+'px;'" --><div class="puzzle-container"><div :style="'position:relative;overflow:hidden;width:'+ dataWidth +'px;'"><div :style="'position:relative;width:' + dataWidth + 'px;height:' + dataHeight + 'px;'"><imgid="scream"ref="scream":src="imgRandom":style="'width:' + dataWidth + 'px;height:' + dataHeight + 'px;'"/><canvas id="puzzle-box" ref="puzzleBox" :width="dataWidth" :height="dataHeight"></canvas></div><divclass="puzzle-lost-box":style="'left:' + left_Num + 'px;width:' + dataWidth + 'px;height:' + dataHeight + 'px;'"><canvas id="puzzle-shadow" ref="puzzleShadow" :width="dataWidth" :height="dataHeight"></canvas><canvas id="puzzle-lost" ref="puzzleLost" :width="dataWidth" :height="dataHeight"></canvas></div><pclass="ver-tips"ref="verTips":style="'height: '+22*scale+'px;line-height:'+22*scale+'px;bottom: ' + (displayTips==true ? 0 : -22*scale ) +'px;font-size: '+12*scale+'px;'"><template v-if="verification"><span :style="'color:#42ca6b;line-height:'+ 22*scale+'px;'">验证通过</span><span :style="'margin-left:'+4*scale+'px;line-height:'+ 22*scale+'px;'">哇喔,怪物吃了拼图,快去登录吧~</span></template><template v-if="!verification"><span :style="'color:red;line-height:'+22*scale+'px;'">验证失败:</span><span :style="'margin-left:'+4*scale+'px;line-height:'+ 22*scale+'px;'">拖动滑块将悬浮图像正确拼合</span></template></p></div><divclass="re-btn"@click="refreshImg":style="'height: '+28*scale+'px;padding: '+1*scale+'px '+16*scale+'px;font-size: '+18*scale+'px;'"><a-icon type="redo" /></div></div><br /><div class="slider-container" :style="'width:' + dataWidth + 'px;'"><div class="slider-bar" :style="'border-radius:'+ 24*scale+'px;'"><pclass="slider-bar-text select-none"onselectstart="return false":style="'line-height:' + 28*scale + 'px;font-size:'+12*scale+'px;'">按住滑块, 拖动完成上方拼图</p></div><divclass="slider-btn"ref="sliderBtn"@mousedown="startMove"@touchstart="startMove":style="'top: '+ -7*scale + 'px;'"><a-icontype="pause-circle"theme="twoTone"twoToneColor="#52c41a":style="'font-size: '+44*scale+'px;'"/><span class="slider-center-zzz">▍▍▍</span></div></div></div></template><script lang="js">export default {name: 'puzzle',data () {return {moveStart: '',displayTips: false,verification: false,randomX: null,randomY: null,imgRandom: '',left_Num: 0,dataWidth: 404,dataHeight: 90,puzzleSize: 100,deviation: 11,scale: 1,reTimer: null,isleavePage: false}},props: {width: {type: [String, Number],default: 340},height: {type: [String, Number],default: 120},cropImage: {type: [Boolean],default: false},puzzleImgList: {type: Array,default: () => ['../../../static/img/a.png',]},PlSize: {type: [String, Number],default: 48},Deviation:{type: [String, Number],default: 4},padding: {type: [Number],default: 20},onSuccess: {type: Function,default: () => {alert('验证成功')}},onError: {type: Function,default: () => {alert('验证失败')}}},methods: {/* 刷新 */RandomNum(Min, Max) {let Range = Max - Min + 1let Rand = Math.random()return Min + Math.floor(Rand * Range)},refreshImg () {let imgRandomNum = this.RandomNum(0, this.puzzleImgList.length-1)this.imgRandom = this.puzzleImgList[imgRandomNum]this.initCanvas()},/* 画布初始化 */initCanvas () {this.clearCanvas()// let self = thislet w = this.dataWidthlet h = this.dataHeight// let PL_Size = 48// 2019-02-12开始PL_Size使用可传递参数let PL_Size = this.puzzleSizelet padding = 20let MinN_X = padding + PL_Sizelet MaxN_X = w - padding - PL_Size - PL_Size / 6let MaxN_Y = paddinglet MinN_Y = h - padding - PL_Size - PL_Size / 6this.randomX = this.RandomNum(MinN_X, MaxN_X)this.randomY = this.RandomNum(MinN_Y, MaxN_Y)let X = this.randomXlet Y = this.randomYthis.left_Num = -X + 10let d = PL_Size / 3let c = this.$refs.puzzleBoxlet c_l = this.$refs.puzzleLostlet c_s = this.$refs.puzzleShadowlet ctx = c.getContext('2d')let ctx_l = c_l.getContext('2d')let ctx_s = c_s.getContext('2d')ctx.globalCompositeOperation = 'xor'ctx.shadowBlur = 10ctx.shadowColor = '#fff'ctx.shadowOffsetX = 3ctx.shadowOffsetY = 3ctx.fillStyle = 'rgba(0,0,0,0.7)'ctx.beginPath()ctx.lineWidth = '1'ctx.strokeStyle = 'rgba(0,0,0,0)'ctx.moveTo(X, Y)ctx.lineTo(X + d, Y)ctx.bezierCurveTo(X + d, Y - d, X + 2 * d, Y - d, X + 2 * d, Y)ctx.lineTo(X + 3 * d, Y)ctx.lineTo(X + 3 * d, Y + d)ctx.bezierCurveTo(X + 2 * d, Y + d, X + 2 * d, Y + 2 * d, X + 3 * d, Y + 2 * d)ctx.lineTo(X + 3 * d, Y + 3 * d)ctx.lineTo(X, Y + 3 * d)ctx.closePath()ctx.stroke()ctx.fill()let img = new Image()img.src = this.imgRandomimg.onload = function () {ctx_l.beginPath()ctx_l.strokeStyle = 'rgbWgbvNDa(0,0,0,0)'ctx_l.moveTo(X, Y)ctx_l.lineTo(X + d, Y)ctx_l.bezierCurveTo(X + d, Y - d, X + 2 * d, Y - d, X + 2 * d, Y)ctx_l.lineTo(X + 3 * d, Y)ctx_l.lineTo(X + 3 * d, Y + d)ctx_l.bezierCurveTo(X + 2 * d, Y + d, X + 2 * d, Y + 2 * d, X + 3 * d, Y + 2 * d)ctx_l.lineTo(X + 3 * d, Y + 3 * d)ctx_l.lineTo(X, Y + 3 * d)ctx_l.closePath()ctx_l.stroke()ctx_l.shadowBlur = 10ctx_l.shadowColor = 'black'ctx_l.clip()ctx_l.drawImage(img, 0, 0, w, h)}ctx_s.beginPath()ctx_s.lineWidth = '1'ctx_s.strokeStyle = 'rgba(0,0,0,0)'ctx_s.moveTo(X, Y)ctx_s.lineTo(X + d, Y)ctx_s.bezierCurveTo(X + d, Y - d, X + 2 * d, Y - d, X + 2 * d, Y)ctx_s.lineTo(X + 3 * d, Y)ctx_s.lineTo(X + 3 * d, Y + d)ctx_s.bezierCurveTo(X + 2 * d, Y + d, X + 2 * d, Y + 2 * d, X + 3 * d, Y + 2 * d)ctx_s.lineTo(X + 3 * d, Y + 3 * d)ctx_s.lineTo(X, Y + 3 * d)ctx_s.closePath()ctx_s.stroke()ctx_s.shadowBlur = 20ctx_s.shadowColor = 'black'ctx_s.fill()},/* 通过重置画布尺寸清空画布,这种方式更彻底 */clearCanvas () {let c = this.$refs.puzzleBoxlet c_l = this.$refs.puzzleLostlet c_s = this.$refs.puzzleShadowc.setAttribute('height', c.getAttribute('height'))c_l.setAttribute('height', c.getAttribute('height'))c_s.setAttribute('height', c.getAttribute('height'))// c.height = c.height// c_l.height = c_l.height// c_s.height = c_s.height},/* 按住滑块后初始化移动监听,记录初始位置 */startMove (e) {console.log(e)e = e || window.eventthis.$refs.sliderBtn.style.backgroundPosition = '0 -216px'this.moveStart = e.pageX || e.targetTouches[0].pageXthis.addMouseMoveListener()},/* 滑块移动 */moving (e) {let self = thise = e || window.eventlet moveX = e.pageX || e.targetTouches[0].pageXlet d = moveX - self.moveStartlet w = self.dataWidthlet PL_Size = this.puzzleSizelet padding = 20if (self.moveStart === '') {return ''}if (d < 0 || d > (w - padding - PL_Size)) {return ''}self.$refs.sliderBtn.style.left = d + 'px'self.$refs.sliderBtn.style.transition = 'inherit'self.$refs.puzzleLost.style.left = d + 'px'self.$refs.puzzleLost.style.transition = 'inherit'self.$refs.puzzleShadow.style.left = d + 'px'self.$refs.puzzleShadow.style.transition = 'inherit'},/* 移动结束,验证并回调 */moveEnd (e) {let self = thise = e || window.eventlet moveEnd_X = (e.pageX || e.changedTouches[0].pageX) - self.moveStartlet ver_Num = self.randomX - 10let deviation = this.deviationlet Min_left = ver_Num - deviationlet Max_left = ver_Num + deviationif (self.moveStart !== '') {if (Max_left > moveEnd_X && moveEnd_X > Min_left) {self.displayTips = trueself.verification = truesetTimeout(function () {if(self.isleavePage){return}self.displayTips = falseself.initCanvas()}, 2000)/* 成功的回调函数 */self.onSuccess()} else {self.displayTips = trueself.verification = falsesetTimeout(function () {if(self.isleavePage){return}self.displayTips = false}, 2000)/* 失败的回调函数 */self.onError()}}if (typeof(self.$refs.sliderBtn) !== 'undefined' && typeof (self.$refs.puzzleLost) !== 'undefined' && typeof (self.$refs.puzzleShadow) !== 'undefined') {self.reTimer = setTimeout(function () {if(self.isleavePage){return}self.$refs.sliderBtn.style.left = 0self.$refs.sliderBtn.style.transition = 'left 0.5s'self.$refs.puzzleLost.style.left = 0self.$refs.puzzleLost.style.transition = 'left 0.5s'self.$refs.puzzleShadow.style.left = 0self.$refs.puzzleShadow.style.transition = 'left 0.5s'}, 1000)self.$refs.sliderBtn.style.backgroundPosition = '0 -84px'}self.moveStart = ''},/* 绑定滑块移动与滑动结束,移动过程中鼠标可在绑定的区域 */addMouseMoveListener () {let self = thisdocument.addEventListener('mousemove', self.moving)document.addEventListener('touchmove', self.moving)document.addEventListener('mouseup', self.moveEnd)document.addEventListener('touchend', self.moveEnd)}},mounted () {let self = thisthis.dataWidth = this.$refs.puzzle.clientWidth*0.884this.dataHeight = this.dataWidth*(this.height/this.width)this.scale = this.$refs.puzzle.clientWidth/260this.puzzleSize = this.dataWidth*(this.PlSize/this.width)setTimeout(self.refreshImg,0)},created () {let imgRandomNum = this.RandomNum(0, this.puzzleImgList.length - 1)this.imgRandom = this.puzzleImgList[imgRandomNum]this.puzzleSize = Number(this.PlSize)this.deviation = Number(this.Deviation)// this.dataWidth = this.width// this.dataHeight = this.height// this.scale = this.width/260},watch: {},beforeDestroy() {this.isleavePage = true}}</script><style scoped>.slider-btn {position: absolute;width: 90px;height: 67px;left: 0;top: -7px;z-index: 12;cursor: pointer;background-position: 0 -84px;transition: inherit;background-color: #f4f7fe;border-radius: 45%;display: flex;}.slider-center-zzz {text-align: center;line-height: 67px;position: absolute;color: #53C300;height: 40px;width: 100%;}.ver-tips {position: absolute;left: 0;bottom: -22px;background: rgba(255, 255, 255, 0.9);height: 22px;line-height: 22px;font-size: 12px;width: 100%;margin: 0;text-align: left;padding: 0 8px;transition: all 0.4s;}.slider-tips {bottom: 0;}.ver-tips i {display: inline-block;width: 22px;height: 22px;vertical-align: top;background-position: -4px -1229px;}.ver-tips span {display: inline-block;vertical-align: top;line-height: 22px;color: #455;}.active-tips {display: block;}.hidden {display: none;}.re-btn {position: absolute;left: 0;bottom: 0;height: 28px;padding: 0 16px;}.re-btn a {display: inline-block;width: 14px;height: 14px;margin: 0px 0;background-position: 0 -1179px;cursor: pointer;}.re-btn a:hover {background-position: 0 -1193px;}.puzzle-container {position: relative;/* padding: 16px 16px 28px; *//* border: 1px solid #ddd; */background: #e0e1e3;/* border-radius: 16px; *//* height: 83px; *//* width: 340px; */}.slider-container {position: relative;margin: auto;}.slider-bar {border: 1px solid #c3c3c3;border-radius: 24px;background: #e0e1e3;box-shadow: 0 1px 1px rgba(12, 10, 10, 0.2) inset;}.slider-bar-text {font-size: 12px;color: #486c80;line-height: 28px;margin: 0;text-align: right;padding-right: 22px;}#puzzle-box {position: absolute;left: 0;top: 0;z-index: 22;}#puzzle-shadow {position: absolute;left: 0;top: 0;z-index: 22;}#puzzle-lost {position: absolute;left: 0;top: 0;z-index: 33;}.puzzle-lost-box {position: absolute;width: 260px;height: 116px;left: 0;top: 0;z-index: 111;}</style>以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
暂时禁止评论













闽公网安备 35020302000061号