HTML5 手势密码实现

在移动端设备上,“手势密码”成为一个很常用的 UI 组件,HTML5画布的出现同样可以实现同样的功能。
这是本人参加360前端实习生星计划的前端作业,主要使用HTML5 画布,JavaScript事件监听,HTML5 LocalStorage来实现。

界面原型







核心思路

点击查看我的GitHub查看所有代码
基于面向的对象的思想,整体JavaScript代码采用立刻执行函数的方法来模拟块级作用域,内部使用构造函数模式和原型模式定义Password方法。
下面列出实现手势密码的核心思路:

如何定义圆的半径和位置

这里设置整个画布为正方形,画布长和宽为cw,每个圆的半径为r,圆与圆之间的距离为2r,最靠近画布边界的圆与画布的距离为2r,这样可以得到公式:

cw = 2r*2+2r*3+2r*2 = 14r

通过画布长宽很容易计算得到每个圆的半径大小和每个圆在画布中的距离,代码如下:

Password.prototype.createCircle = function () {
this.r = this.context.canvas.width/14; //圆圈半径
for(var i = 0;i < 3;i++){
for(var j = 0;j <3;j++){
//圆心坐标,相对于画布的位置
var center = {
x: i * 4 * this.r + 3 * this.r,
y: j * 4 * this.r + 3 * this.r,
}
this.circleArr.push(center);
this.restPoints.push(center);
}
}
this.context.clearRect(0,0,this.context.canvas.width,this.context.canvas.height);
for(var key in this.circleArr){
this.drawCircle(this.circleArr[key].x,this.circleArr[key].y);
}
};

如何判断设置还是验证状态

我们给每个input Radio添加了监听事件,在Password中设置了构造属性status,通过点击事件实时更新status中的状态

Password.prototype.getStatus = function () {
var radios = document.querySelectorAll('input[type=radio]');
var self = this;
radios.forEach(function (item) {
item.addEventListener('click',function (event) {
self.status = event.target.value;
},false);
});
};

如何监听触摸移动

利用lastPoints来存储经历的圆心,利用restPoints存储没经历过所剩下的圆心点。在画布中添加三个触摸监听事件:touchstart,touchmove,touchend.
在touchstart和touchmove中事件中不断判断触摸事件的当前位置与每个圆的距离,如果距离小于r,则把该圆心点添加到lastPoints中,restPoints也相应去掉该圆心点。

需要touchmove是很耗性能的,特别是对于大型图片来说,低配置的手机容易出现图片卡顿的现象。由于手势密码比较简单,所以性能消耗方面不是很明显。

在touchend中判断密码是否设置成功或者失败。

其他代码是画布和localstorage的操作代码,没有做过多解释,详情请参看JavaScript中的代码。