微信小程序-滑动拼图安全验证
滑动拼图验证组件1. 前提介绍2. 最终实现效果图3. 封装验证组件并使用1.编写组件2.引入并使用4. 总结1. 前提介绍本项目是应用taro框架使用Canvas 画布组件微信开发文档来实现的注此组件目前是纯前端校验没涉及后端2. 最终实现效果图3. 封装验证组件并使用1.编写组件话不多说直接上代码viewtemplate!-- 滑动验证弹窗 --viewclassmask puzzleVerify-maskv-ifvisible:catch-movetrueviewclasscontiner_box puzzleVerify-content!-- 弹窗头部 --viewclassmodal-headertextclassmodal-title安全验证/textviewclassmodal-closetaponCloseimagestylewidth: 100%; height: 100%srchttps://yunqi-dy-public.tos-cn-beijing.volces.com/files/20260317/13bb166726b5446fba307934cdb0bf71.png//view/viewviewclasspuzzleVerify-box!-- 提示文字 --viewclasspuzzle-tiptextclasstip-text拖动滑块完成拼图验证/text/view!-- 拼图图片部分 --viewclasscanvas_imgidcanvas_img:style{ position: relative, zIndex: 0 }!-- 背景图片 --!--canvas :style{ width: canvas_width px, height: canvas_height px, border: 1rpx solid transparent, }idfirstCanvastype2d/canvas--canvasidfirstCanvastype2d/canvas!-- 被抠方块 --viewclasscanvas_view:style{ left: canfile_x px, top: canfile_y px, position: absolute, zIndex: 3, }/view!-- 可移动空格 --imageclasscanfile_image:style{ top: canfile_y px, left: (slide_clientX canvas_width - 50 ? canvas_width - 50 : slide_clientX) px, position: absolute, zIndex: 4, }:srccanfile_image/imageclassrefresg-iconsrchttps://yunqi-dy-public.tos-cn-beijing.volces.com/files/20260317/27a0a2ac09074b62b941f0e1288ed3b7.pngtaponDrawCanvas//view/view!-- 滑块 --viewclasscanvas-slideviewclasscanvas-slide-width:style{ width: [2, 3].includes(slide_status) ? 100% : slide_clientX canvas_width ? canvas_width : slide_clientX px, background: slide_status 2 ? #52CCBA : slide_status 3 ? #F57A7A : , }/viewview v-ifslide_status 0 || slide_status 1classcanvas-slide-btn fcctouchstartonSliderStarttouchmoveonSliderMovetouchendonSliderEnd:style{ left: slide_clientX canvas_width ? canvas_width : slide_clientX px, }view→/view/viewviewclasscanvas-slide-tipv-ifslide_status 0 || slide_status 1拖动左边滑块完成上方拼图/viewview v-elseclasscanvas-slide-tip canvas-slide-tip2{{slide_status2?验证成功:验证失败请重试}}/view/view/view/view/templatescriptimportTaro fromtarojs/taro;import./puzzleVerify.scss;exportdefault{props:{value:{type: Boolean, default: false,},},data(){return{visible: false, canvas_width:0, canvas_height:0, slidebel: false, //滑动弹窗 canfile_image:, //裁剪图片 canfile_x:, //被抠方块的水平位置 canfile_y:, //被抠方块的垂直位置 slide_clientX:0, //移动位置 slide_status:0, //0 停止操作1触发长按2正确3错误 puzzleImages:[https://i.postimg.cc/JDjqt4tw/bg1.jpg,https://i.postimg.cc/3J5HYcPP/bg4.png,https://i.postimg.cc/zBs4DyPQ/bg2.png,],};}, watch:{value(newVal){this.visiblenewVal;if(newVal){setTimeout((){const queryTaro.createSelectorQuery();query .select(#canvas_img).boundingClientRect((rect){if(rect){console.log(rect, rect);this.canvas_widthrect.width;this.canvas_heightMath.floor(rect.width *0.5);// 宽高比2:1 setTimeout((){this.onDrawCanvas();},200);}}).exec((rect){});},500);}},}, methods:{onClose(){this.$emit(input,false);}, // 画布 onDrawCanvas(e){var thatthis;//获取图片条数的随机数 var imgIndexMath.floor(Math.random()* this.puzzleImages.length);this.canfile_xMath.round(Math.random()*(this.canvas_width -120)60);this.canfile_yMath.round(Math.random()*((this.canvas_width *13)/28-60));this.canfile_image;Taro.createSelectorQuery().select(#firstCanvas)// 在 WXML 中填入的id.fields({node: true, size:true}).exec((res){// Canvas 对象 const canvasres[0].node;// 渲染上下文 const ctxcanvas.getContext(2d);// Canvas 画布的实际绘制宽高 const widthres[0].width;const heightres[0].height;// 初始化画布大小 const dprwx.getWindowInfo().pixelRatio;canvas.widthwidth * dpr;canvas.heightheight * dpr;ctx.scale(dpr, dpr);const imagecanvas.createImage();// 设置图片src image.srcthis.puzzleImages[imgIndex];// 图片加载完成回调 image.onload(){// 将图片完整绘制到 canvas 上 ctx.drawImage(image,0,0, width, height);// 绘制完成后可以添加一些调试信息 console.log(图片绘制完成尺寸:, image.width, image.height);console.log(Canvas尺寸:, width, height);};//一定要加延时器不然图片会生成失败 setTimeout((){// 生成图片 Taro.canvasToTempFilePath({canvas, x: that.canfile_x, y: that.canfile_y, width:60, height:60, success:(res){// 生成的图片临时文件路径 that.canfile_imageres.tempFilePath;console.log(tempFilePath, that.canfile_image);},}, this);},500);});}, // 滑动开始 onSliderStart(e){this.slide_status1;}, // 滑动中 onSliderMove(e){this.slide_clientXe.touches[0].clientX -301?0:e.touches[0].clientX -30;}, //滑动结束 onSliderEnd(e){var thatthis;var cliextX;var maxXthis.canvas_width -30;if(that.slide_clientX1){that.slide_status0;returnfalse;}if(that.slide_clientXmaxX){cliextXmaxX;}else{cliextXthat.slide_clientX;}if(that.canfile_x 5cliextXthat.canfile_x -5cliextX){that.slide_status2;that.slide_clientXthat.canfile_x;setTimeout(function(){that.slidebelfalse;},500);wx.showToast({icon:success, title:验证成功,});this.$emit(onSuccess);this.onClose();}else{that.slide_status3;}setTimeout(function(){that.slide_status0;that.slide_clientX0;},500);},},};/script/* 拼图滑动验证 */ .puzzleVerify-mask{.puzzleVerify-content{position: relative;padding: 50rpx 30rpx!important;box-sizing: border-box;}/* 弹窗头部 */ .modal-header{display: flex;align-items: center;justify-content: space-between;padding: 0rpx 0rpx 30rpx;border-bottom: 2rpx solid#f5f5f5;.modal-title{font-size: 32rpx;font-weight:600;color:#333333;}.modal-close{width: 48rpx;height: 48rpx;}}.puzzleVerify-box{padding-top: 30rpx;.puzzle-tip{text-align: center;margin-bottom: 24rpx;.tip-text{font-size: 28rpx;color:#666666;}}.canvas_img{position: relative;width:100%;height: 300rpx;margin-bottom: 40rpx;border-radius: 12rpx;overflow: hidden;background:#f8f9fa;}#firstCanvas {z-index:1!important;width:100%;height:100%;}/* 被抠的空格 */ .canvas_view{width: 50px;height: 50px;position: absolute;background: rgba(0,0,0,0.6);z-index:2;box-shadow:005px 2px rgba(255,255,255,0.5);}/* 移动的空格 */ .canfile_image{width: 50px;height: 50px;position: absolute;left:0;z-index:3;box-shadow: 0px 0px 15px rgba(0,0,0,0.8);box-sizing: border-box;}.canfile_image::before{content:;position: absolute;width:100%;height:100%;box-shadow:008px 5px rgba(255,255,255,0.8)inset;}.refresg-icon{position: absolute;top: 20rpx;right: 20rpx;width: 48rpx;height: 48rpx;z-index:5;}}}.canvas-slide{width:100%;height: 60rpx;background:#e5e5e5;text-align: center;position: relative;font-size: 26rpx;overflow: hidden;/* 滑条上滑块经过的部分 */ .canvas-slide-width{position: absolute;left:0;top:0;height: 60rpx;background-color:#1991fa;width:0;border-top: 1px solid#ddd;border-bottom: 1px solid#ddd;z-index:2;}/* 滑块 */ .canvas-slide-btn{width: 80rpx;height: 60rpx;background-color:#1991fa;font-size: 36rpx;font-weight:700;position: absolute;left:0;top:0;border: 1px solid#ddd;color:#fff;box-shadow:0010px rgba(0,0,0,0.3);z-index:2;}.canvas-slide-tip{width:100%;position: absolute;top:50%;left:50%;transform: translate(-50%, -50%);text-align: center;font-size: 24rpx;color:#fff;transition: color0.3s ease;z-index:1;}.canvas-slide-tip.canvas-slide-tip2{z-index:4;}}2.引入并使用templateviewview taponShowVerity获取验证码/viewpuzzleVerify v-modelisShowVerifyonSuccessonVerifySuccess//view/templatescriptimportpuzzleVerify from/components/puzzleVerify/puzzleVerify.vue;exportdefault{components:{puzzleVerify},data(){return{isShowVerify: false, //安全校验弹窗};}, methods:{onVerifySuccess(){console.log(验证通过-------------);},onShowVerity(){this.isShowVerifytrue;},}};/script4. 总结注上面的方式是有应用到实际项目当中去的正常获取流程是没问题的如果在开发在过程中遇到问题可以发出来一起交流呢
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2429506.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!