1、参考地址:https://www.cnblogs.com/huang...2、效果:3、逻辑:拖动底部滑块控制小拼图的移动,当其左边距与x坐标一致时切割位置的,或者在一定范围内,是正确的;难点在于切出拼图,这一步参考上述链接地址;4、项目地址:https://gitee.com/beiysd/reac...5、部分源码如下:/***@nameBlockImgMove*@descriptionSlidingPuzzleValidation*/importReact,{Component}from"react";importTitlefrom"@/component/Title";import{Icon,Spin}from"antd";import{main}from"@/utils/base64";importstylesfrom"./styles.module.less";constimgSrc=require("@/assets/img/10355.jpg");constcanWidth=300;//容器宽度constcanHeight=160;//容器高度constcanLitWidth=42;//图片滑块宽度constcanLitR=10;//Slider自带小圆半径constcanLitL=canLitWidth+canLitR*2+3;//小拼图的实际边长为constPI=Math.PI;//周长比例classBlockImgMoveextendsComponent{state={blockX:0,//小拼图X轴坐标textMess:"向右移动拼图完成验证",type:false,//验证status,False表示验证失败,true表示验证成功loading:false,//loadingstatuscanvasRand:"",blockRand:"",imgPath:""};y=0;//小拼图的Y轴坐标xreached=0;//X轴坐标img=null;componentDidMount(){this.onMouseDown();这个文件吨();}init=()=>{this.y=0;这个.x=0;//this.img=null;this.setState({type:false,blockX:0,textMess:"右移并拼接图片,完成验证",canvasRand:`canvas${this.getRandomNumberByRange(0,100)}`,//"canvasRand",//this.getRandomNumberByRange(0,100)blockRand:`block${this.getRandomNumberByRange(0,100)}blockRand:`block${this.getRandomNumberByRange(0,100)(101,200)}`//"blockRand"//this.getRandomNumberByRange(101,200)},()=>{this.getImg();});};/***@nameonMouseDown*@description监听鼠标点击*/onMouseDown=()=>{letoutBox=document.getElementById("out_mouse_img");让mouseBox=document.getElementById("mouse_img");让那个=这个;mouseBox.onmousedown=function(ev){让ev00=ev||窗口事件;让px=ev00.pageX;//初始位置,对于整个页面,光标点击位置letoL=this.offsetLeft;//初始位置,对于有定位的父级,元素边框边与父边框边的距离初始为0mouseBox.onmousemove=function(evs){if(that.state.type){return;}让ev01=evs||窗口事件;让px1=ev01.pageX;//滑动后当前鼠标位置letoL1=px1-px+oL;//从初始位置移动的距离if(oL1<=0){oL1=0;}elseif(oL1>outBox.clientWidth-mouseBox.clientWidth){oL1=outBox.clientWidth-mouseBox.clientWidth;}//console.log("oL1===",oL1);that.setState({blockX:oL1});};mouseBox.onmouseup=function(){that.cancelMove();};};};/***@nametextChange*@description校验成功,messageChange*/textChange=()=>{this.setState({textMess:"校验成功",type:true});};/***@namecancelMove*@description当鼠标离开滑块时,滑块停止滑动并复位*/cancelMove=()=>{letmouseBox=document.getElementById("mouse_img");让mouseLeft=mouseBox.offsetLeft;mouseBox.onmousemove=null;if(mouseLeft!==0)if(mouseLeft===this.x||(mouseLeft<=this.x+3&&mouseLeft>=this.x-3)){//验证成功的不可逆操作this.onmousemove=无效的;mouseBox.onmousemove=null;这个.textChange();}else{this.init();}};/***@namegetRandomNumberByRange*@description获取随机数*/getRandomNumberByRange=(start,end)=>{returnMath.round(Math.random()*(结束-开始)+开始);};/***@namegetImg*@description获取在线图片,图片资源和项目地址来源不同,导致跨域,需要跨域处理*/getImg=async()=>{consturl=`/api-online-img/${canWidth}/${canHeight}/?image=${this.getRandomNumberByRange(1,100)}`;尝试{this.setState({loading:true});//不同源图片,这里是先将在线图片转成base64,再渲染,需要多1-2秒main(url,(base64)=>{//在线图片报错切换到本地图片this.setState({imgPath:base64?base64:imgSrc},()=>{this.setState({loading:false});this.drawInit();});});}catch(error){console.log("err==",error);}};/***@namedraw*@description公共绘图方法*/draw=(ctx,x=0,y=0,w=0,operation)=>{letr=canLitR;ctx.beginPath();ctx.moveTo(x,y);ctx.arc(x+w/2,y-r+2,r,0.72*PI,2.26*PI);ctx.lineTo(x+w,y);ctx.arc(x+w+r-2,y+w/2,r,1.21*PI,2.78*PI);ctx.lineTo(x+w,y+w);ctx.lineTo(x,y+w);ctx.arc(x+r-2,y+w/2,r+0.4,2.76*PI,1.24*PI,真);ctx.lineTo(x,y);ctx.line宽度=2;ctx.fillStyle="rgba(255,255,255,0.7)";ctx.strokeStyle="rgba(255,255,255,0.7)";ctx.stroke();ctx.globalCompositeOperation="destination-over";操作===“填充”?ctx.fill():ctx.剪辑();};/***@namedrawInit*@description绘制前的处理*/drawInit=async()=>{const{canvasRand,blockRand,imgPath}=this.state;constmycanvas=document.getElementById(canvasRand);constmyblock=document.getElementById(blockRand);myblock.width=canWidth;//得到等宽的整幅图像constcanvas_ctx=mycanvas.getContext("2d");constblock_ctx=myblock.getContext("2d");//清空画布canvas_ctx.clearRect(0,0,canWidth,canHeight);block_ctx.clearRect(0,0,canWidth,canHeight);这个.img=document.createElement("img");//创建一个小图像滑块//在随机位置创建一个拼图形状this.x=this.getRandomNumberByRange(canLitL+10,canWidth-(canLitL+10));this.y=this.getRandomNumberByRange(10+canLitR*2,canHeight-(canLitL+10));//渲染图像this.img.onload=async()=>{canvas_ctx.drawImage(this.img,0,0,canWidth,canHeight);block_ctx.drawImage(this.img,0,0,canWidth,canHeight);让_y=this.y-canLitR*2-1;//small拼图的实际坐标letImgData=block_ctx.getImageData(this.x-5,_y-3,canLitL,canLitL);myblock.width=canLitL;//小拼图的宽度,隐藏抠图位置图片block_ctx.putImageData(ImgData,0,_y);};this.img.src=imgPath;//图片路径this.draw(canvas_ctx,this.x,this.y,canLitWidth,"fill");this.draw(block_ctx,this.x,this.y,canLitWidth,"clip");};render(){const{textMess,type,blockX,loading,canvasRand,blockRand}=this.state;return(
