JavaScript實現拖動滑塊拼圖驗證功能(html5、canvas)
阿新 • • 發佈:2021-03-19
引言:
滑塊拖動驗證現在很多地方都用到,週末就琢磨著寫了一個,放上來,看看有沒有人用得上! 效果:
實現思路:
用一張畫布繪製源圖,再繪製一個填充的方形,這樣就可以達到缺失的效果(方形的座標是隨機的);
再用一個畫布繪製拖動塊,同時用drawImage擷取和上一步中方形區域一樣座標、大小的原圖,就作為驗證圖了,把驗證圖放在最左邊;
在拖動塊處,按下滑鼠然後拖動,拖動塊和驗證圖會跟隨滑鼠移動,達到一定範圍後放開滑鼠,會進行驗證;
驗證通過則提示驗證成功,驗證不通過則拖動塊和驗證圖會返回到最左邊。
3個建構函式 圖片建構函式
//圖片對程式設計客棧象ImageDraw建構函式
function ImageDraw(o,obj){
this.id='',this.image=0,//圖片物件(必填)
this.sx=0,//圖片切片開始x位置(顯示整個圖片的時候不需要填)
this.sy=0,//圖片切片開始y位置(顯示整個圖片的時候不需要填)
this.sWidth=0,//圖片切片開始寬度(顯示整個圖片的時候不需要填)
this.sHeight=0,//圖片切片開始高度(顯示整個圖片的時候不需要填)
this.dx=0,//圖片目標x位置(必填)
this.dy=0,//圖片目標y位置(必填)
this.dWidth=0,//圖片目標顯示寬度(寬度不縮放時不必填)
this.dHeight=0//圖片目標高度高度(高度不縮放時不必填)
this.init(o,obj);
}
ImageDraw.prototype.init=function(o,obj){
for(var key in o){
this[key]=o[key];
}
return this;
}
ImageDraw.prototype.render=function(context){
draw(context,this);
function draw(context,obj) {
var ctx=context;
ctx.save();
if(!obj.image || getType(obj.dx)=='undefined' || getType(obj.dy)=='undefined'){
throw new Error("繪製圖片缺失引數");
return;
}
ctx.translate(obj.dx,obj.dy);
if(getType(obj.sx)!='undefined' && getType(obj.sy)!='undefined' && obj.sWidth && obj.sHeight && obj.dWidth && obj.dHeight){
//裁剪圖片,顯示時候有縮放
ctx.drawImage(obj.image,obj.sx,obj.sy,obj.sWidth,obj.sHeight,obj.dWidth,obj.dHeight);
}else if(obj.dWidth && obj.dHeight){
ctx.drawImage(obj.image,obj.dHeight);//原始圖片,顯示時候有縮放
}else{
ctx.drawImage(obj.image,0);//原始圖片,顯示時候無縮放
}
ctx.restore();
}
}
ImageDraw.prototype.isPoint=function(pos){
//滑鼠位置的x、y要分別大於dx、dy 且x、y要分別小於 dx+dWidth、dy+dHeight
if(pos.x>this.dx && pos.y>this.dy && pos.x<this.dx+this.dWidth && pos.y<this.dy+this.dHeight ){//表示處於當前圖片物件範圍內
return true;
}
return false;
}
方形建構函式
function Rect(o){ this.x=0,//x座標 this.y=0,//y座標 this.width=100,//寬 程式設計客棧 this.height=40,//高 this.thin=true,//線段薄一點 this.init(o); } Rect.prototype.init=function(o){ for(var key in o){ this[key]=o[key]; } } Rect.prototype.render=function(context){ this.ctx=context; innerRender(this); function innerRender(obj){ var ctx=obj.ctx; ctx.save() ctx.beginPath(); ctx.translate(obj.x,obj.y); if(obj.lineWidth){ ctx.lineWidth=obj.lineWidth; } if(obj.thin){ ctx.translate(0.5,0.5); } ctx.rect(0,obj.width,obj.height); if(obj.fill){//是否填充 obj.fillStyle?(ctx.fillStyle=obj.fillStyle):null; ctx.fill(); } if(obj.stroke){//是否描邊 obj.strokeStyle?(ctx.strokeStyle=obj.strokeStyle):nullwww.cppcns.com; ctx.stroke(); } ctx.restore(); } return this; }
文字建構函式
function Text(o){ this.x=0,//y座標 this.text=http://www.cppcns.com'',//內容 this.font=null;//字型 this.textAlign=null;//對齊方式 this.init(o); } Text.prototype.init=function(o){ for(var key in o){ this[key]=o[key]; } } Text.prototype.render=function(context){ this.ctx=context; innerRender(this); function innerRender(obj){ var ctx=obj.ctx; ctx.save() ctx.beginPath(); ctx.translate(obj.x,obj.y); if(obj.font){ ctx.font=obj.font; } if(obj.textAlign){ ctx.textAlign=obj.textAlign; } if(obj.fill){//是否填充 obj.fillStyle?(ctx.fillStyle=obj.fillStyle):null; ctx.fillText(obj.text,0); } ctx.restore(); } return this; }
繪製源圖和缺失塊
var img = new ImageDraw({image:this.imgObj[0],dx:0,dy:0,dWidth:640,dHeight:360},this); this.renderArr.push(img); var x=_.getRandom(100,580);//x從100-580之間取 var y=_.getRandom(0,300);//y從0-300之間取 this.validPos={x:x,y:y}; //缺失塊繪製 var rect = new Rect({ x:x,y:y,width:60,height:60,fill:true,fillStyle:'gray' }) this.renderArr.push(rect); //繪製驗證塊長條 var rect = new Rect({ x:0,y:360,width:640,height:40,fillStyle:'#E8E8E8' }) this.renderArr.push(rect); //繪製文字 var text = new Text({ x:300,y:390,text:'拖動滑塊驗證',font:'18px serif',textAlign:'center',//fillStyle:'white' }); this.renderArr.push(text);
此時頁面效果如下
繪製驗證圖和拖動塊
注意:驗證圖的繪製座標與上一步繪製缺失塊的座標是一樣的。
var pos = this.validPos;//上一步繪製缺失塊的座標,驗證圖需根據這個座標來擷取 var img = new ImageDraw({image:this.imgObj[0],sx:pos.x,sy:pos.y,sWidth:60,sHeight:60,dy:pos.y,dWidth:60,dHeight:60},this); this.renderArr2.push(img); var img1 = new ImageDraw({image:this.imgObj[1],dy:360,dWidth:40,dHeight:40},this); this.renderArr2.push(img1);
效果圖:
畫布2新增事件
//給canvas畫布新增點選事件 canvas2.addEventListener('mousedown',this.mouseDown.bind(this)); canvas2.addEventListener('mouseup',this.mouseUp.bind(this)); canvas2.addEventListener('mousemove',this.mouseMove.bind(this));
滑鼠按下事件
- 記錄滑鼠按下時的x座標,保持滑鼠移動不飄。
- 改變移動標記為true,防止沒有拖動滑塊而產生移動的效果。
Slider.prototype.mouseDown=function(e){ var pos = _.getOffset(e);//獲取滑鼠位置 if(!this.block) return ; if(this.block.isPoint(pos)){//按下的位置是滑塊的位置 this.move=true;//表示可以移動 this.downX=pos.x;//記錄滑鼠按下的位置,保持移動 } }
滑鼠移動事件
- 驗證圖和滑塊移動時需減去滑鼠點選的初始X座標。
- 當超過一定範圍則不能再移動,防止移出畫布範圍。
Slider.prototype.mouseMove=function(e){ if(!this.move) return ;//移動標記為false則直接返回 var pos = _.getOffset(e); pos.x -= this.downX;//要減去滑鼠初始點選的位置 if(pos.x>580){ return ; } this.update(pos);//移動 } //更新 Slider.prototype.update=function(pos){ //更改滑塊和驗證圖的座標 _.each(this.renderArr2,function(item){ if(item){ item.dx=pos.x; } }); //繪製 this.render(); }
滑鼠放開事件
- 滑鼠移動move標記為false;
- 未達到驗證範圍而放開滑鼠,滑塊和驗證圖會回到最左邊;
- 當驗證圖的移動達到一定範圍,則表示驗證通過;
驗證通過後,提示驗證通過,相關內容要做出改變,比如缺失塊的清除、提示文字內容的改變等;
Slider.prototype.mouseUp=function(e){ this.move=false; var pos = _.getOffset(e); pos.x -= this.downX; var validPos = this.validPos;程式設計客棧//驗證快的座標 if(Math.abs(pos.x-validPos.x )<=10){//驗證通過(x位置的差值多少範圍內即可) console.log('通過') this.suc(); }else{//驗證不通過 this.update({x:0}); } this.render(); } Slider.prototype.suc=function(){ this.renderArr.splice(2,1);//清楚缺失塊 this.block=null; //滑塊和驗證圖的清除 this.renderArr2.length=0; //長條顏色的改變 this.renderArr[1].fillStyle='#78C430'; var text = this.renderArr[2]; //提示內容的改變 text.fillStyle='white'; text.text="驗證成功"; }
成功後如下:
完整程式碼下載
到此這篇關於javascript實現拖動滑塊拼圖驗證(html5、canvas)的文章就介紹到這了,更多相關js實現拖動滑塊拼圖驗證內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!