利用JS 事件 与 Cnavas绘图 以及 H5 缓存写的一个手势解锁(三)

来源:互联网 发布:淘宝c店开店流程 编辑:程序博客网 时间:2024/06/06 14:07

上一篇结合在canvas原理中,绘制了手势解锁的初始界面,我们也知道,手势解锁的难点不在于初始界面的绘制,而在于手势移动过程中界面的一系列变化,包括触摸到的点的颜色变化,以及添加的线条路径,这些都是得通过JS交互来实现的,在这个应用中,主要涉及的是JS HTML5事件中的触摸事件。

回顾一下,(一)里面的JS事件机制和触摸事件:
touchstart: 开始触摸时触发
touchend: 在触摸结束时触发
touchmove: 在触发移动过程中触发。注意:在移动设备上触摸移动时会默认触发滚动事件,因此利用perventDefalut()将其默认行为取消。
每个触发事件都对应的事件对象。对于touchstart和touchmove事件,事件对象中有一个touches数组,这里面包括触摸的clientX,clientY,target等属性信息。

在各个触摸事件都了解的情况下,我们应该思考各个事件处理程序应该如何写,也就是一开始按下某点的时候如何操作,结束触摸时如何响应,以及在触摸移动过程中又该有什么样的操作。下面我们一个一个来解决。

  1. touchstart事件
    在一开始触摸移动设备时,应该对于触摸到的点进行填充。
    如何确定触摸到的点是哪一个?(利用触摸点与9个点圆心之间的距离,小于半径r就认为是哪个点)
for(var num = 0; num< pointArr.length; num++){    var CurrX = e.touches[0].clientX - pointArr[num].x;    var CurrY = e.touches[0].clientY - pointArr[num].y;    var dis = Math.pow((Math.pow(CurrX, 2) + Math.pow( CurrY, 2)), 0.5);    if(dis <= r)    {        //console.log(pointArr[num].id);        //对这个点着色        DrawColor(pointArr[num].x, pointArr[num].y);        //LineArr.push(pointArr[num]);        break;    }}

当第二次开始触摸时,又应该将之前的绘制路径清空。然后再对触摸点进行颜色填充表示该点已选。

if(Count >= 2){    ctx.clearRect(0, 0, 1200, 1200);    //把颜色都设为white,然后去填充和描边;    DrawCirclePanel(pointArr);    for(var i = 0; i < pointArr.length; i++)    {        pointArr[i].visited = false;    }}

2.touchmove事件
由于在touchmove事件触发时,H5默认会触发滚动事件,因此首先要取消事件的默认行为。

var handlerMove = function(e){    e.preventDefault();

另外,在触摸移动过程中,需要把选择的点进行填充,再根据选择的点画出一条路径,我们可以考虑用绘制路径的lineTo(x,y)来实现。不难想到,要画线,必须知道点的圆心坐标才可以画出点到点的线。因此,引入一个数组LineArr来保存已选中的那些点是必要的。

CurrX = e.touches[0].clientX - pointArr[num].x;CurrY = e.touches[0].clientY - pointArr[num].y;dis = Math.pow((Math.pow(CurrX, 2) + Math.pow( CurrY, 2)), 0.5);/*console.log(dis);*/if(dis <= r){    pointArr[num].visited = true;                               //对这个点着色    DrawColor(pointArr[num].x, pointArr[num].y);    //还要划线;需要知道前后的点的坐标;可以考虑这样来做:    //即把划到的那些点都push进一个数组里,然后只需沿着数组中这些点的坐标画线就可以                              LineArr.push(pointArr[num]);}//接下来对LineArr中的点连线if(LineArr.length > 1){    var len = LineArr.length;    ctx.strokeStyle = "rgba(255,255,10, 0.8)";    DrawLine(LineArr[len - 2], LineArr[len - 1]);}

这样,在触摸过程中的基本处理就结束了。
3. touchend事件
在触摸结束之后,我们该如何处理呢?
一种就是该过程是设置手势密码的过程:
该情况下的事件处理程序主要做的就是将绘制的密码存到LocalStorage中。
注意:LocalStoarge只能存储字符串,因存储时要将object对象转换为字符串(调用JSON.stringify)

var localS = window.localStorage;localS.setItem('result', JSON.stringify(LineArr));     //localStorage 只能保存字符串setLock = false;  //将全局变量setLock设为false,表示下一次将是解锁过程

另一种是解锁过程:
该情况下的事件处理程序主要做这几件事:
先将得到缓存中的密码;
将取到的密码与本次绘制的密码相比较。

var getStorage = localS.getItem("result");       //localStorage 只能保存字符串,因此取出来也只能是字符串格式,因此将其转换为JSON格式var res = JSON.parse(getStorage);if(res.length != LineArr.length){    alert('两次输入的密码长度不一致,请重新解锁!');    setLock = false;}else{    for(var i = 0; i < LineArr.length; i++)    {        if(res[i].id != LineArr[i].id)        {            alert("两次输入的密码不一致,请重新解锁!");            break;            setLock = false;        }    }    if(i == LineArr.length)    {        alert("解锁成功!");        setLock = true;    }}

下面说说H5缓存的Localstorage和SessionStorage吧。
两者都是在客户端进行存储的,但是也有区别。
LocalStorage必须手动清除才会消失,不然,一旦保存就不会消失;
而sessionStorage属于会话级别的,当浏览器窗口关闭之后保存的这个信息就不在了。

至此,本次手势解锁过程结束。当然,还存在有两个问题,后面还会改进。至于源代码,可以访问我的Github地址:https://github.com/DangDangHellen/GestureLock

阅读全文
0 0