JavaScript實現(xiàn)拖動滑塊拼圖驗證功能(html5、canvas)
引言:
滑塊拖動驗證現(xiàn)在很多地方都用到,周末就琢磨著寫了一個,放上來,看看有沒有人用得上! 效果:

實現(xiàn)思路:
用一張畫布繪制源圖,再繪制一個填充的方形,這樣就可以達到缺失的效果(方形的坐標(biāo)是隨機的);
再用一個畫布繪制拖動塊,同時用drawImage截取和上一步中方形區(qū)域一樣坐標(biāo)、大小的原圖,就作為驗證圖了,把驗證圖放在最左邊;
在拖動塊處,按下鼠標(biāo)然后拖動,拖動塊和驗證圖會跟隨鼠標(biāo)移動,達到一定范圍后放開鼠標(biāo),會進行驗證;
驗證通過則提示驗證成功,驗證不通過則拖動塊和驗證圖會返回到最左邊。
3個構(gòu)造函數(shù) 圖片構(gòu)造函數(shù)
//圖片對象ImageDraw構(gòu)造函數(shù)
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, //圖片目標(biāo)x位置(必填)
this.dy=0, //圖片目標(biāo)y位置(必填)
this.dWidth=0,//圖片目標(biāo)顯示寬度(寬度不縮放時不必填)
this.dHeight=0//圖片目標(biāo)高度高度(高度不縮放時不必填)
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("繪制圖片缺失參數(shù)");
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, 0, 0, obj.dWidth, obj.dHeight);
}else if(obj.dWidth && obj.dHeight){
ctx.drawImage(obj.image, 0, 0, obj.dWidth, obj.dHeight);//原始圖片,顯示時候有縮放
}else{
ctx.drawImage(obj.image,0, 0);//原始圖片,顯示時候無縮放
}
ctx.restore();
}
}
ImageDraw.prototype.isPoint=function(pos){
//鼠標(biāo)位置的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 ){//表示處于當(dāng)前圖片對象范圍內(nèi)
return true;
}
return false;
}
方形構(gòu)造函數(shù)
function Rect(o){
this.x=0,//x坐標(biāo)
this.y=0,//y坐標(biāo)
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,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):null;
ctx.stroke();
}
ctx.restore();
}
return this;
}
文本構(gòu)造函數(shù)
function Text(o){
this.x=0,//x坐標(biāo)
this.y=0,//y坐標(biāo)
this.text='',//內(nèi)容
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,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,
fill:true,
fillStyle:'#E8E8E8'
})
this.renderArr.push(rect);
//繪制文字
var text = new Text({
x:300,
y:390,
text:'拖動滑塊驗證',
font:'18px serif',
textAlign:'center',
fill:true,
//fillStyle:'white'
});
this.renderArr.push(text);
此時頁面效果如下

繪制驗證圖和拖動塊
注意:驗證圖的繪制坐標(biāo)與上一步繪制缺失塊的坐標(biāo)是一樣的。
var pos = this.validPos;//上一步繪制缺失塊的坐標(biāo),驗證圖需根據(jù)這個坐標(biāo)來截取
var img = new ImageDraw({image:this.imgObj[0],sx:pos.x,sy:pos.y,sWidth:60,sHeight:60,dx:0, dy:pos.y,dWidth:60,dHeight:60},this);
this.renderArr2.push(img);
var img1 = new ImageDraw({image:this.imgObj[1],dx:0, 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));
鼠標(biāo)按下事件
- 記錄鼠標(biāo)按下時的x坐標(biāo),保持鼠標(biāo)移動不飄。
- 改變移動標(biāo)記為true,防止沒有拖動滑塊而產(chǎn)生移動的效果。
Slider.prototype.mouseDown=function(e){
var pos = _.getOffset(e);//獲取鼠標(biāo)位置
if(!this.block) return ;
if(this.block.isPoint(pos)){//按下的位置是滑塊的位置
this.move=true;//表示可以移動
this.downX=pos.x;//記錄鼠標(biāo)按下的位置,保持移動
}
}
鼠標(biāo)移動事件
- 驗證圖和滑塊移動時需減去鼠標(biāo)點擊的初始X坐標(biāo)。
- 當(dāng)超過一定范圍則不能再移動,防止移出畫布范圍。
Slider.prototype.mouseMove=function(e){
if(!this.move) return ;//移動標(biāo)記為false則直接返回
var pos = _.getOffset(e);
pos.x -= this.downX;//要減去鼠標(biāo)初始點擊的位置
if(pos.x>580){
return ;
}
this.update(pos);//移動
}
//更新
Slider.prototype.update=function(pos){
//更改滑塊和驗證圖的坐標(biāo)
_.each(this.renderArr2,function(item){
if(item){
item.dx=pos.x;
}
});
//繪制
this.render();
}
鼠標(biāo)放開事件
- 鼠標(biāo)移動move標(biāo)記為false;
- 未達到驗證范圍而放開鼠標(biāo),滑塊和驗證圖會回到最左邊;
- 當(dāng)驗證圖的移動達到一定范圍,則表示驗證通過;
驗證通過后,提示驗證通過,相關(guān)內(nèi)容要做出改變,比如缺失塊的清除、提示文字內(nèi)容的改變等;
Slider.prototype.mouseUp=function(e){
this.move=false;
var pos = _.getOffset(e);
pos.x -= this.downX;
var validPos = this.validPos;//驗證快的坐標(biāo)
if(Math.abs(pos.x-validPos.x )<=10){//驗證通過(x位置的差值多少范圍內(nèi)即可)
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];
//提示內(nèi)容的改變
text.fillStyle='white';
text.text="驗證成功";
}
成功后如下:

到此這篇關(guān)于JavaScript實現(xiàn)拖動滑塊拼圖驗證(html5、canvas)的文章就介紹到這了,更多相關(guān)js實現(xiàn)拖動滑塊拼圖驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實現(xiàn)通過表格繪制顏色填充矩形的方法
這篇文章主要介紹了javascript實現(xiàn)通過表格繪制顏色填充矩形的方法,涉及javascript操作表格與樣式的相關(guān)技巧,需要的朋友可以參考下2015-04-04

