canvas之手势锁屏

这个是效果图

思想:
  解锁
 1、动态设置画布
 2、绘制画布上面的圆圈
 3、当触屏点在圆圈内时让该圆圈内添加实心圆,并让touchflag为true
 3、如果touchmove触发并且touchflag为true时执行update函数,该函数接受的是po(x,y)当前鼠标相对于画布的坐标
 4、update函数是先清空画布,然后在画布上面绘制所有的圆圈,并且通过lastPoint这个储存解锁时经过点位置的数组,来重新绘制
 实线和实心圆,最终lineTo(po.x,po.y),并判断此时点的位置是否在圆圈中,如果在就把该点储存的到lastPoint,并且在剩余点的
 数组restPoint中删除该点
 5、点鼠标弹起时触发touchend事件,iftouchPoint为true的时候让touchFlag变为false,然后判断该解锁手势是否正确。

判断方法:
 通过lastPoint.index这个属性,index是数字1-9表示这九个圆圈,每当鼠标经过一个圆圈时lastPoint就会储存这个圆圈的x,y,index 就是该圆圈圆心的xy坐标,以及第几个圆圈,这样密码就变成'123'之类的字符串,如果密码正确就进行对应的样式显示,反之亦然
 
 设置解屏密码
 1、先创建setPwd对象,增加flag和flag1属性,初始都为false,flag是当点击设置密码之后会变成true
 2、当flag为true的时候,就开始进行第一次手势设置,第一次手势设置好之后显示对应的样式,
 并且flag 变成false,flag1变成true进行手势解锁的确定(一般设置密码都要进行两次确定,第二次是判断本次设置的是否和第一次一样),如果一样就把pwd 赋予该密码,然后显示对应的样式。该部分操作都是在canvasLock.prototype.judge,只要在这两个判断后面加个return就可以拦截 下面手势密码验证这一部分,而进行手势密码设置,当两次设置都完成无误后,将flag和flag1都变成false就行了,就可以进行解锁功能了
 

    首先是创建canvasLock这个对象,并且设置width(画布的宽)、height(画布的高)、chooseType(每行1圆得数量)、pwd(解锁手势,用数字表示的字符串)属性

    window.canvasLock=function(obj){
		this.width=obj.width;
		this.height=obj.height;
		this.chooseType=obj.chooseType;
		this.pwd='';
	}

 初始化程序

    canvasLock.prototype.init=function(){
		this.createDom();
		this.canvas = document.getElementById('canvas');
        this.ctx = this.canvas.getContext('2d');
        this.createCircle();
        this.bindEvent();
		this.touchFlag=false;
		
	}

js动态创建Dom结构 

	canvasLock.prototype.createDom=function(){
		var div=document.createElement('div');
		var str='<h4 id="title" class="title">绘制解锁图案</h4>';
		div.setAttribute('style','position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;');
		div.innerHTML=str;
		
		var canvas=document.createElement('canvas');
		//给canvas设置css样式
        canvas.style.cssText = 'background-color: #305066;display: inline-block;margin-top: 15px;';
		canvas.setAttribute('id','canvas');
		
		canvas.width=this.width||300;
		canvas.height=this.height||300;
		
		div.appendChild(canvas);
		//设置密码Dom
		var btn=document.createElement('div');
		btn.innerHTML='设置密码';
		btn.setAttribute('id','btn');
		btn.setAttribute('style','width:100px;height: 50px;border: 1px red solid;line-height: 50px;');
		div.appendChild(btn);
		
		document.body.appendChild(div);		
	}

创建锁屏上的圆圈,并且给对象添加属性arr储存所有点的数组、lastPoint储存描绘过点的数组、restPoint储存剩余点的数组。

    canvasLock.prototype.createCircle=function(){
		
		var index=0;//第几个点
		var num=this.chooseType;
		
		this.r=this.canvas.height/(num*2+1)/2;
		this.arr=[];//储存每个圆的圆心坐标
		this.lastPoint=[];//绘制过圆的圆心坐标
		this.restPoint=[];//没绘制过圆的圆心坐标
		//获取中心点的坐标,并加入到数组中
		for(var i=0;i<num;i++){
			for(var j=0;j<num;j++){
				index++;
				var obj={
					x:j*4*this.r+3*this.r,
					y:i*4*this.r+3*this.r,
					index:index
				};
				this.arr.push(obj);
				this.restPoint.push(obj);
			}
		}

		//画圆圈
		this.drawCil();
	}

 

创建锁屏上圆圈的函数

	canvasLock.prototype.drawCil=function(){
		for(var i=0;i<this.arr.length;i++){
			this.ctx.beginPath();
			this.ctx.strokeStyle = '#CFE6FF';
            this.ctx.lineWidth = 2;
			this.ctx.arc(this.arr[i].x,this.arr[i].y,this.r,0,Math.PI*2,true);
			this.ctx.closePath();
			this.ctx.stroke();
		}
	}

获取点击的位置相对画布的距离,

	canvasLock.prototype.getPosition=function(e){
		var rect = e.currentTarget.getBoundingClientRect();
		
        var po = {
            x: (e.touches[0].clientX - rect.left),
            y: (e.touches[0].clientY - rect.top)
        };
        return po;
	}

画实心圆

	canvasLock.prototype.drawPoint=function(x,y){
		this.ctx.beginPath();
		this.ctx.fillStyle = '#CFE6FF';
		this.ctx.arc(x,y,this.r/2,0,Math.PI*2,true);
		this.ctx.fill();
	}

点击事件

canvasLock.prototype.bindEvent=function(){
		var that=this;
		
		this.canvas.addEventListener('touchstart',function(e){
			var po=that.getPosition(e);
			//判断该点是否在圆圈内,如果在绘制圆中圆
			for(var i=0;i<that.arr.length;i++){
				if(Math.sqrt(Math.pow(that.arr[i].x-po.x,2)+Math.pow(that.arr[i].y-po.y,2))<=that.r){
					that.drawPoint(that.arr[i].x,that.arr[i].y);
					//添加到过去的点数组中
					that.lastPoint.push(that.arr[i]);
					//从剩余的点中删除这一个
					that.restPoint.splice(i,1);
					
					that.touchFlag=true;
                    break;
				}
			}
		},false);
		
		this.canvas.addEventListener('touchmove',function(e){			
			if(that.touchFlag){
				var po=that.getPosition(e);
				that.update(po);
			}
		},false)
		
		this.canvas.addEventListener('touchend',function(){
			if(that.touchFlag){
				that.judge();
				setTimeout(function(){
					that.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
					that.createCircle();
				},300)
				that.touchFlag=false;
			}
		},false)
	}

 

画所有经过的点的函数

	canvasLock.prototype.drawP=function(){
		for(var i=0;i<this.lastPoint.length;i++){
			this.drawPoint(this.lastPoint[i].x,this.lastPoint[i].y);
		}
	}

画解锁时点与点之间的连线 

	canvasLock.prototype.drawLine=function(po){
		this.ctx.beginPath();
		this.ctx.lineWidth = 3;
		this.ctx.moveTo(this.lastPoint[0].x,this.lastPoint[0].y);
		for(var i=1;i<this.lastPoint.length;i++){
			this.ctx.lineTo(this.lastPoint[i].x,this.lastPoint[i].y)		
		}
		this.ctx.lineTo(po.x,po.y);
		this.ctx.stroke();
	}

 当开始解锁时对画布进行更新

	canvasLock.prototype.update=function(po){
		//清空画布
		this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
		//画空心圆
		this.drawCil();
		//画圆心圆
		this.drawP();
		//画线
		this.drawLine(po);
		
		// 1、检测手势移动的位置是否处于下一个圆内
        // 2、圆内的话则画圆 drawPoint
        // 3、已经画过实心圆的圆,无需重复检测
		for(var i=0;i<this.restPoint.length;i++){
			if(Math.sqrt(Math.pow(this.restPoint[i].x-po.x,2)+Math.pow(this.restPoint[i].y-po.y,2))<=this.r){
				this.drawPoint(this.restPoint[i].x,this.restPoint[i].y);
				//添加到过去的点数组中
				this.lastPoint.push(this.restPoint[i]);
				//从剩余的点中删除这一个
				this.restPoint.splice(i,1);
                   break;
			}
		}
	}

判断解锁是否正确

	canvasLock.prototype.judge=function(){
		//
		var p='';console.log(a.flag);
		if(a.flag){
			this.pwd='';
			for(var i=0;i<this.lastPoint.length;i++){
				this.pwd+=this.lastPoint[i].index;
			}
			this.drawStatusPoint('#2CFF26');
			document.getElementById('title').innerHTML = '请确认解锁手势';
			a.flag=false;
			a.flag1=true;
			return;
		}
		if(a.flag1){
			for(var i=0;i<this.lastPoint.length;i++){
				p+=this.lastPoint[i].index;
			}
			if(p===this.pwd){
				this.drawStatusPoint('#2CFF26');
				document.getElementById('title').innerHTML = '解锁手势设置成功,可尝试解锁';
				a.flag1=false;
				a.flag=false;
			}else{
				this.drawStatusPoint('red');
				document.getElementById('title').innerHTML = '与上一次不一样,请再次设置';
			}
			return;
		}
		//上面那一部分是设置密码的
		//var pwd='123';
		var inputPwd='';
		for(var i=0;i<this.lastPoint.length;i++){
			inputPwd+=this.lastPoint[i].index;
		}0
		if(inputPwd===this.pwd){
			document.getElementById('title').innerHTML = '解锁成功';
            this.drawStatusPoint('#2CFF26');
		}else{
			document.getElementById('title').innerHTML = '解锁失败';
            this.drawStatusPoint('red');
		}
	}
	 canvasLock.prototype.drawStatusPoint = function(type) {
        for (var i = 0 ; i < this.lastPoint.length ; i++) {
            this.ctx.strokeStyle = type;
            this.ctx.beginPath();
            this.ctx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.r, 0, Math.PI * 2, true);
            this.ctx.closePath();
            this.ctx.stroke();
        }
    }

 设置密码

	//设置密码
	window.setPwd=function(){
		this.flag=false;//是否在设置密码
		this.flag1=false;//是否确认密码
	}	
	var a=new setPwd();
	setPwd.prototype.init=function(){
		this.btn=document.getElementById('btn');	
		
		this.run();
	}
	setPwd.prototype.run=function(){
		this.btn.ontouchstart=function(){
			a.flag=true;
			document.getElementById('title').innerHTML = '请设置解锁手势';
		}
		console.log(this)
	}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值