js+cavans實(shí)現(xiàn)圖片滑塊驗(yàn)證
本文實(shí)例為大家分享了js+cavans實(shí)現(xiàn)圖片滑塊驗(yàn)證的具體代碼,供大家參考,具體內(nèi)容如下
js已封裝好,拿來即用,兼容pc端和移動(dòng)端,
效果:
移動(dòng)端:

pc端:

原理就不解釋了,我之前的博客已經(jīng)說過,只不過這個(gè)版本是結(jié)合了canvas實(shí)現(xiàn),又兼容了pc端,直接拿代碼就能用了。
代碼:html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.sliderModel {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
display: none;
}
.sliderModel .cont{padding: 20px; width: 280px; background: #fff;border-radius: 6px;margin: 50px auto;}
.showMessage {
text-align: center;
font-size: 14px;
height: 30px;
line-height: 30px;
}
#canvas_wrap{
width: 280px;
}
#canvas_wrap canvas{
display: block;
}
</style>
</head>
<body>
<div class="sliderModel">
<div class="cont">
<div id="canvas_wrap"></div>
<div class="showMessage"></div>
</div>
<div id="close">關(guān)閉</div>
</div>
<div id="open">打開</div>
</body>
<script src="newSlider.js"></script>
<script>
function showMessage(msg,color){
var showMessage = document.querySelector('.showMessage');
showMessage.innerHTML=msg;
showMessage.style.color=color;
}
var obj={
el:'#canvas_wrap',
w:280,
h:150,
imgArr:['images/sliderz/1.jpg','images/sliderz/2.jpg','images/sliderz/3.jpg','images/sliderz/4.jpg'],
sliderIcon:'images/sliderz/sangangy.png',
refresh:function(){
showMessage('','#333')
},
finish:function(e){
e? showMessage('驗(yàn)證成功!','green') : showMessage('驗(yàn)證失敗,請(qǐng)重試','red');
}
}
document.querySelector('#open').onclick=function(){ //打開
document.querySelector('.sliderModel').style.display="block";
new window.$newSlider(obj);
}
document.querySelector('#close').onclick=function(){ //關(guān)閉
document.querySelector('.sliderModel').style.display="none";
}
</script>
</html>
newSlider.js:
(function(){
function slider(params){
var obj={
el:params.el,
w:params.w || 280, //canvas的寬度
h:params.h || 150, //canvas的高度
range:params.range || 5, //相差多少像素內(nèi)觸發(fā)成功
imgArr:params.imgArr || [], //圖片數(shù)組
sliderW:36, //slider的邊長(zhǎng)
sliderIcon:params.sliderIcon || '',
refresh:params.refresh, //刷新回調(diào)
finish:params.finish , //完成回調(diào)
};
//創(chuàng)建canvas的父元素
var container=document.querySelector(obj.el);
container.innerHTML='';
var canvas_wrap=document.createElement('div');
canvas_wrap.className="canvas_wrap";
canvas_wrap.style.cssText="position:relative;overflow:hidden;border-radius:4px;width:"+obj.w+"px;height:"+obj.h+"px;background:#fff"
//創(chuàng)建大小canvas元素
var bigCanvas=document.createElement('canvas');
var smartCanvas=bigCanvas.cloneNode(true);
bigCanvas.width=smartCanvas.width=obj.w;
bigCanvas.height=smartCanvas.height=obj.h;
bigCanvas.style.cssText=smartCanvas.style.cssText="position:absolute;left:0;top:0";
var bcxt=bigCanvas.getContext('2d'),scxt=smartCanvas.getContext('2d'),img=new Image();
//創(chuàng)建標(biāo)題和刷新按鈕
var titleDom=document.createElement('div');
var refreshDom=document.createElement('div');
titleDom.className="slider_title";
refreshDom.className="slider_refresh";
titleDom.style.cssText="position:relative;width:"+obj.w+"+px;height:60px;text-align:center;font-size:18px; line-height:60px";
refreshDom.style.cssText="position:absolute;top:0;right:14px;font-size:14px;color:green;cursor: pointer";
titleDom.innerHTML="圖形驗(yàn)證";
refreshDom.innerHTML="刷新";
//創(chuàng)建拖拽區(qū)域
var slider_wrap=document.createElement('div'),slider=document.createElement('div'),sliderCover=document.createElement('div');
slider_wrap.className="slider_wrap";
slider.className="canvas_slider";
sliderCover.className="sliderCover";
slider_wrap.innerText="拖動(dòng)左邊滑塊完成上方拼圖";
slider_wrap.style.cssText="width:"+obj.w+"px;height:30px; border-radius:30px;line-height:30px; position:relative;margin-top:10px;text-align:center;box-shadow: inset 0 0 4px #ccc;font-size: 14px;color:#999";
slider.style.cssText="cursor: pointer;position: absolute;left: 0;top: 50%;z-index: 2;height: "+obj.sliderW+"px;width: "+obj.sliderW+"px;background:rgb(0, 124, 255) url("+obj.sliderIcon+") no-repeat center;background-size: 60% 60%;border-radius: "+obj.sliderW+"px;line-height:"+obj.sliderW+"px;text-align:center;transform: translateY(-50%);";
sliderCover.style.cssText="position: absolute;left: 0;top:0;width:0;height:100%;background:#eee;border-radius:30px;"
slider_wrap.appendChild(slider);
slider_wrap.appendChild(sliderCover);
canvas_wrap.appendChild(bigCanvas);
canvas_wrap.appendChild(smartCanvas);
titleDom.appendChild(refreshDom);
container.appendChild(titleDom);
container.appendChild(canvas_wrap);
container.appendChild(slider_wrap);
var canvasCoverL=0,startDownX=0,smartCanvasBL=0,sliderMaxRange=obj.w-obj.sliderW;
/*
canvasCoverL:隨機(jī)生成占位塊canvas的x軸位置
startDownX://鼠標(biāo)按下時(shí)x軸位置
smartCanvasBL: 可移動(dòng)canvas的left初始值
sliderMaxRange:slider可移動(dòng)的最大距離
*/
//生成canvas圖案
function creatCanvas(){
//重置初始值
canvasCoverL=0;startDownX=0;smartCanvasBL=0;
slider.style.left = sliderCover.style.width = 0;
var l= 40, //滑塊的正方形邊長(zhǎng),不包括小圓點(diǎn)
r = 10, //小圓點(diǎn)半徑
PI = Math.PI,
sliderW=l+2*r, //滑塊邊長(zhǎng)
rand=canvasSize(sliderW,r), //獲取隨機(jī)生成的x,y,left值
x = canvasCoverL= rand.x, //占位塊x軸
y = rand.y; //占位塊y軸
smartCanvasBL=rand.left;
//先清空畫布
bcxt.clearRect(0, 0, obj.w, obj.h)
scxt.clearRect(0, 0, obj.w, obj.h)
smartCanvas.width=obj.w;
var srcIndex=Math.floor(Math.random()*(obj.imgArr.length-1));
img.src=obj.imgArr[srcIndex];
draw(scxt,x,y,l,r,PI,'clip');
draw(bcxt,x,y,l,r,PI,'fill');
img.onload = function() { //一定要在onload里調(diào)用,否則canvas里不能放進(jìn)圖片
bcxt.drawImage(img,0,0,obj.w,obj.h);
scxt.drawImage(img,0,0,obj.w,obj.h);
//裁剪滑塊長(zhǎng)度
var ImageData = scxt.getImageData(x, y-2*r, sliderW, sliderW)
smartCanvas.width = sliderW;
smartCanvas.style.left=rand.left+"px";
scxt.putImageData(ImageData, 0, y-2*r)
}
obj.refresh && obj.refresh();
}
//隨機(jī)生成canvas滑塊和占位塊,到左邊的距離和到頂部的距離
function canvasSize(cw,r){
// cw為占位塊和的寬度,r為繪制圓點(diǎn)的半徑
var random =Math.random();
var x=Math.floor(obj.w/2 + random*(obj.w/2 - cw)); //x為占位塊x坐標(biāo)位置,保證占位塊始終在畫布的右半?yún)^(qū)域
var y=Math.floor(r*2+random*(obj.h - cw - r*2)); //y為占位塊y坐標(biāo)位置,(值至少為小圓半徑的2倍才能完全顯示,因?yàn)槔L制的原點(diǎn)是小正方形的左上角)
var left =Math.floor(random*(obj.w/2 - cw)); //canvas滑塊的left值,這里的值范圍保證它始終在畫布的左半?yún)^(qū)域
return {x:x,y:y,left:left}
}
//繪制canvas滑塊和占位塊
function draw(ctx,x,y,l,r,PI,operation) {
ctx.beginPath()
ctx.moveTo(x, y)
ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
ctx.lineTo(x + l, y)
ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
ctx.lineTo(x + l, y + l)
ctx.lineTo(x, y + l)
ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
ctx.lineTo(x, y)
ctx.lineWidth = 1
ctx.fillStyle = 'rgba(200, 200, 200, 1)'
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
ctx.stroke()
ctx[operation]()
ctx.globalCompositeOperation = 'destination-over'
}
//滑塊被按下
function moveStart(e){
var ev = e || window.event;
startDownX = ev.touches!=undefined? ev.touches[0].clientX : ev.clientX;
}
//滑塊移動(dòng)
function moveProcess(e){
var ev = e || window.event,downX = (ev.touches!=undefined)? ev.touches[0].clientX : (startDownX!=0? ev.clientX : 0),range=downX-startDownX;
console.log(downX)
var sliderRange= range<=0? 0 : (range<sliderMaxRange ? range : sliderMaxRange);
slider.style.left=sliderRange+"px";
sliderCover.style.width=obj.sliderW/2 + sliderRange +"px";
smartCanvas.style.left=smartCanvasBL+sliderRange+"px";
}
//停止滑動(dòng)
function moveEnd(e){
var ev = e || window.event;
ev.touches!=undefined? slider.ontouchmove=null : slider.onmousemove=null;
var smartCanvasL= parseInt(smartCanvas.style.left);
if(Math.abs(canvasCoverL - smartCanvasL) < obj.range){
obj.finish && obj.finish(true);
}else{
obj.finish && obj.finish(false);
var timer = null,step = 10;
var sliderL = parseInt(slider.style.left)
timer = setInterval(function () {
sliderL -= step;
step += 5;
if (sliderL <= 0) {
clearInterval(timer);
sliderL = 0;
slider.style.left = sliderCover.style.width = 0;
smartCanvas.style.left = smartCanvasBL + "px"
}
slider.style.left = sliderL + "px";
sliderCover.style.width = sliderL+obj.sliderW/2 +"px";
smartCanvas.style.left = sliderL + smartCanvasBL+ "px";
}, 20)
}
}
//事件調(diào)用
creatCanvas();
refreshDom.onclick=refreshDom.ontouchstart=creatCanvas;
slider.ontouchstart=function(){
moveStart();
this.ontouchmove=moveProcess;
this.ontouchend=moveEnd;
};
slider.onmousedown=function(){
moveStart();
this.onmousemove=moveProcess;
this.onmouseup=moveEnd;
};
}
window.$newSlider=slider
})()
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js+canvas實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲
這篇文章主要為大家詳細(xì)介紹了js+canvas實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
微信小程序賬號(hào)密碼登入和傳值的實(shí)現(xiàn)方法
傳統(tǒng)的web開發(fā)實(shí)現(xiàn)登陸功能,一般的做法是輸入賬號(hào)密碼、或者輸入手機(jī)號(hào)及短信驗(yàn)證碼進(jìn)行登錄,下面這篇文章主要給大家介紹了關(guān)于微信小程序賬號(hào)密碼登入和傳值的實(shí)現(xiàn)方法,需要的朋友可以參考下2022-04-04
javascript函數(shù)中參數(shù)傳遞問題示例探討
本節(jié)主要與大家探討下javascript函數(shù)中參數(shù)傳遞問題,有不明白的朋友可以參考下2014-07-07
javascript網(wǎng)頁關(guān)鍵字高亮代碼
非常不錯(cuò)的關(guān)鍵字高亮代碼,用js實(shí)現(xiàn),這個(gè)方法不錯(cuò)2008-07-07
JS 中document.write()的用法和清空的原因淺析
這篇文章主要介紹了JS 中document.write()的用法和清空的原因淺析,需要的朋友可以參考下2017-12-12
In Javascript Class, how to call the prototype method.(three
In Javascript Class, how to call the prototype method.(three method)...2007-01-01

