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

上一篇结合在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值