H5完毕显示屏手势解锁,HTML5落实显示器手势解锁

HTML5贯彻显示器手势解锁

2015/07/18 · HTML5 · 1
评论 ·
手势解锁

初稿出处:
AlloyTeam   

职能显示

皇家赌场手机版 1

大吉大利原理 利用HTML5的canvas,将解锁的框框划出,利用touch事件解锁那个规模,直接看代码。

JavaScript

function createCircle() {//
创建解锁点的坐标,依照canvas的分寸来平均分配半径 var n = chooseType;//
画出n*n的矩阵 lastPoint = []; arr = []; restPoint = []; r =
ctx.canvas.width / (2 + 4 * n);// 公式计算 半径和canvas的高低有关 for
(var i = 0 ; i < n ; i++) { for (var j = 0 ; j < n ; j++) {
arr.push({ x: j * 4 * r + 3 * r, y: i * 4 * r + 3 * r });
restPoint.push({ x: j * 4 * r + 3 * r, y: i * 4 * r + 3 * r }); }
} //return arr; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function createCircle() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径
 
        var n = chooseType;// 画出n*n的矩阵
        lastPoint = [];
        arr = [];
        restPoint = [];
        r = ctx.canvas.width / (2 + 4 * n);// 公式计算 半径和canvas的大小有关
        for (var i = 0 ; i < n ; i++) {
            for (var j = 0 ; j < n ; j++) {
                arr.push({
                    x: j * 4 * r + 3 * r,
                    y: i * 4 * r + 3 * r
                });
                restPoint.push({
                    x: j * 4 * r + 3 * r,
                    y: i * 4 * r + 3 * r
                });
            }
        }
        //return arr;
    }

canvas里的圆形画好以往可以展开事件绑定

JavaScript

function bindEvent() { can.addEventListener(“touchstart”, function (e) {
var po = getPosition(e); console.log(po); for (var i = 0 ; i <
arr.length ; i++) { if (Math.abs(po.x – arr[i]皇家赌场手机版,.x) < r &&
Math.abs(po.y – arr[i].y) < r) { // 用来判定初始点是或不是在规模内部
touchFlag = true; drawPoint(arr[i].x,arr[i].y);
lastPoint.push(arr[i]); restPoint.splice(i,1); break; } } }, false);
can.addEventListener(“touchmove”, function (e) { if (touchFlag) {
update(getPosition(e)); } }, false); can.addEventListener(“touchend”,
function (e) { if (touchFlag) { touchFlag = false; storePass(lastPoint);
setTimeout(function(){ init(); }, 300); } }, false); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function bindEvent() {
        can.addEventListener("touchstart", function (e) {
             var po = getPosition(e);
             console.log(po);
             for (var i = 0 ; i < arr.length ; i++) {
                if (Math.abs(po.x – arr[i].x) < r && Math.abs(po.y – arr[i].y) < r) { // 用来判断起始点是否在圈圈内部
 
                    touchFlag = true;
                    drawPoint(arr[i].x,arr[i].y);
                    lastPoint.push(arr[i]);
                    restPoint.splice(i,1);
                    break;
                }
             }
         }, false);
         can.addEventListener("touchmove", function (e) {
            if (touchFlag) {
                update(getPosition(e));
            }
         }, false);
         can.addEventListener("touchend", function (e) {
             if (touchFlag) {
                 touchFlag = false;
                 storePass(lastPoint);
                 setTimeout(function(){
 
                    init();
                }, 300);
             }
 
         }, false);
    }

随后到了最重大的手续绘制解锁路径逻辑,通过touchmove事件的不停触发,调用canvas的moveTo方法和lineTo方法来画出折现,同时判断是或不是达到大家所画的范畴里面,其中lastPoint保存不易的规模路径,restPoint保存全体规模去除正确路线之后剩余的。
Update方法:

JavaScript

function update(po) {// 宗旨转移形式在touchmove时候调用 ctx.clearRect(0,
0, ctx.canvas.width, ctx.canvas.height); for (var i = 0 ; i <
arr.length ; i++) { // 每帧先把面板画出来 drawCle(arr[i].x,
arr[i].y); } drawPoint(lastPoint);// 每帧花轨迹 drawLine(po ,
lastPoint);// 每帧画圆心 for (var i = 0 ; i < restPoint.length ; i++)
{ if (Math.abs(po.x – restPoint[i].x) < r && Math.abs(po.y –
restPoint[i].y) < r) { drawPoint(restPoint[i].x,
restPoint[i].y); lastPoint.push(restPoint[i]); restPoint.splice(i,
1); break; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function update(po) {// 核心变换方法在touchmove时候调用
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
 
        for (var i = 0 ; i < arr.length ; i++) { // 每帧先把面板画出来
            drawCle(arr[i].x, arr[i].y);
        }
 
        drawPoint(lastPoint);// 每帧花轨迹
        drawLine(po , lastPoint);// 每帧画圆心
 
        for (var i = 0 ; i < restPoint.length ; i++) {
            if (Math.abs(po.x – restPoint[i].x) < r && Math.abs(po.y – restPoint[i].y) < r) {
                drawPoint(restPoint[i].x, restPoint[i].y);
                lastPoint.push(restPoint[i]);
                restPoint.splice(i, 1);
                break;
            }
        }
 
    }

说到底就是甘休工作,把路子里面的lastPoint保存的数组变成密码存在localstorage里面,之后就用来拍卖解锁验证逻辑了

JavaScript

function storePass(psw) {// touchend为止之后对密码和景色的处理 if
(pswObj.step == 1) { if (checkPass(pswObj.fpassword, psw)) { pswObj.step
= 2; pswObj.spassword = psw; document.getElementById(‘title’).innerHTML
= ‘密码保存成功’; drawStatusPoint(‘#2CFF26’);
window.localStorage.setItem(‘passwordx’,
JSON.stringify(pswObj.spassword));
window.localStorage.setItem(‘chooseType’, chooseType); } else {
document.getElementById(‘title’).innerHTML = ‘一回不均等,重新输入’;
drawStatusPoint(‘red’); delete pswObj.step; } } else if (pswObj.step ==
2) { if (checkPass(pswObj.spassword, psw)) {
document.getElementById(‘title’).innerHTML = ‘解锁成功’;
drawStatusPoint(‘#2CFF26’); } else { drawStatusPoint(‘red’);
document.getElementById(‘title’).innerHTML = ‘解锁失利’; } } else {
pswObj.step = 1; pswObj.fpassword = psw;
document.getElementById(‘title’).innerHTML = ‘再一次输入’; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function storePass(psw) {// touchend结束之后对密码和状态的处理
        if (pswObj.step == 1) {
            if (checkPass(pswObj.fpassword, psw)) {
                pswObj.step = 2;
                pswObj.spassword = psw;
                document.getElementById(‘title’).innerHTML = ‘密码保存成功’;
                drawStatusPoint(‘#2CFF26’);
                window.localStorage.setItem(‘passwordx’, JSON.stringify(pswObj.spassword));
                window.localStorage.setItem(‘chooseType’, chooseType);
            } else {
                document.getElementById(‘title’).innerHTML = ‘两次不一致,重新输入’;
                drawStatusPoint(‘red’);
                delete pswObj.step;
            }
        } else if (pswObj.step == 2) {
            if (checkPass(pswObj.spassword, psw)) {
                document.getElementById(‘title’).innerHTML = ‘解锁成功’;
                drawStatusPoint(‘#2CFF26’);
            } else {
                drawStatusPoint(‘red’);
                document.getElementById(‘title’).innerHTML = ‘解锁失败’;
            }
        } else {
            pswObj.step = 1;
            pswObj.fpassword = psw;
            document.getElementById(‘title’).innerHTML = ‘再次输入’;
        }
 
    }

解锁组件

将以此HTML5解锁写成了一个零件,放在

二维码体验: 皇家赌场手机版 2

 

参考资料:

1 赞 4 收藏 H5完毕显示屏手势解锁,HTML5落实显示器手势解锁。 1
评论

皇家赌场手机版 3

皇家赌场手机版 4

用 canvas 完结 Web 手势解锁

2017/04/04 · HTML5 ·
Canvas

初稿出处: songjz   

近年来列席 360 暑假的前端星安排,有一个在线作业,截至日期是 3 月 30
号,让手动落成一个 H5 手势解锁,具体的职能就好像原生手机的九宫格解锁那样。

皇家赌场手机版 5

贯彻的末段效果就好像上面那张图那样:

皇家赌场手机版 6

骨干须要是那般的:将密码保存到 localStorage
里,早先的时候会从本土读取密码,假若没有就让用户设置密码,密码最少为五位数,少于五位要升迁错误。需要对第五次输入的密码举行认证,四回一样才能保持,然后是注脚密码,可以对用户输入的密码举办求证。

前些天亟需在网页上画一个图谱,想到用JS,经过上学,和网上查找,经过整理优化得到上面代码,注意不是用HTML5的canvas,而是用的纯js

贯彻原理利用HTML5的canvas,将解锁的层面划出,利用touch事件解锁那些层面,直接看代码。

H5 手势解锁

扫码在线查看:

皇家赌场手机版 7

恐怕点击查看手机版。

项目 GitHub
地址,H5HandLock。

先是,小编要说美赞臣(Beingmate)下,对于那么些项目,小编是参照外人的,H5lock。

本人认为一个相比较合理的解法应该是应用 canvas 来促成,不亮堂有没有大神用 css
来完毕。若是纯用 css 的话,能够将连线先安装
display: none,当手指划过的时候,突显出来。光设置这么些本该就丰富费力呢。

事先通晓过 canvas,但不曾真的的写过,上面就来介绍本身这几天学习 canvas
并贯彻 H5 手势解锁的进度。

复制代码 代码如下:

functioncreateCircle(){//
创制解锁点的坐标,根据canvas的深浅来平均分配半径

绸缪桑土及布局设置

自家那里用了一个相比较正规的做法:

(function(w){ var handLock = function(option){} handLock.prototype = {
init : function(){}, … } w.handLock = handLock; })(window) // 使用 new
handLock({ el: document.getElementById(‘id’), … }).init();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(function(w){
  var handLock = function(option){}
 
  handLock.prototype = {
    init : function(){},
    …
  }
 
  w.handLock = handLock;
})(window)
 
// 使用
new handLock({
  el: document.getElementById(‘id’),
  …
}).init();

健康办法,相比易懂和操作,弊端就是,可以被随机的改动。

传扬的参数中要包括一个 dom 对象,会在这几个 dom 对象內成立一个
canvas。当然还有部分其余的 dom 参数,比如 message,info 等。

关于 css 的话,懒得去新建文件了,就径直內联了。

/* 以下画点,画线,画圆的不二法门,都不是用HTML5的canvas,而是用的纯js
用到了有些数学的三角函数方法
以下代码是课堂随机写出,没有做越多优化
*/
/*
面向对象封装,添加绘制矩形
尤其优化代码
*/
var Graphics = function(divId, color){
this.divId = divId;
this.color = color; //’#000000’或’black’
this.drawPoint= function(x,y){
//画点
var oDiv=document.createElement(‘div’);
H5完毕显示屏手势解锁,HTML5落实显示器手势解锁。oDiv.style.position=’absolute’;
oDiv.style.height=’2px’;
oDiv.style.width=’2px’;
oDiv.style.backgroundColor=this.color;
oDiv.style.left=x+’px’;
oDiv.style.top=y+’px’;
//document.body.appendChild(oDiv);
return oDiv;//注意:再次回到的值是一个dom节点,但没有追加到文档中
};
this.drawLine = function(x1,y1,x2,y2){
//画一条线段的主意。(x1,y1),(x2,y2)分别是线段的起源终点
var x=x2-x1;//宽
var y=y2-y1;//高
var frag=document.createDocumentFragment();
if(Math.abs(y)>Math.abs(x)){//那么些边更长,用那边来做画点的依据(就是上边那么些循环),假若不那样,当是一条垂直线或水平线的时候,会画不出去
if(y>0)//正着画线是那样的
for(var i=0;i<y;i++){
var width=x/y*i
//x/y是直角多个边长的比,依照那么些比例,求出新坐标的职位
{

varn = chooseType;// 画出n*n的矩阵

canvas

frag.appendChild(drawPoint(width+x1,i+y1));
}
}
if(y<0){//有时候是倒着画线的
for(var i=0;i>y;i–){
var width=x/y*i
{
frag.appendChild(drawPoint(width+x1,i+y1));
}
}
}
}//end if
else {

lastPoint = [];

1. 学学 canvas 并消除画圆

MDN
上边有个不难的课程,大概浏览了一下,感觉还行。Canvas教程。

先成立一个 canvas,然后设置其大小,并由此 getContext
方法得到绘画的上下文:

var canvas = document.createElement(‘canvas’); canvas.width =
canvas.height = width; this.el.appendChild(canvas); this.ctx =
canvas.getContext(‘2d’);

1
2
3
4
5
var canvas = document.createElement(‘canvas’);
canvas.width = canvas.height = width;
this.el.appendChild(canvas);
 
this.ctx = canvas.getContext(‘2d’);

然后呢,先画 n*n 个圆出来:

JavaScript

createCircles: function(){ var ctx = this.ctx, drawCircle =
this.drawCircle, n = this.n; this.r = ctx.canvas.width / (2 + 4 * n) //
那里是参考的,感觉那种画圆的章程挺合理的,方方圆圆 r = this.r;
this.circles = []; // 用来存储圆心的职位 for(var i = 0; i < n;
i++){ for(var j = 0; j < n; j++){ var p = { x: j * 4 * r + 3 * r,
y: i * 4 * r + 3 * r, id: i * 3 + j } this.circles.push(p); } }
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); //
为了防患再度画 this.circles.forEach(function(v){ drawCircle(ctx, v.x,
v.y); // 画每一种圆 }) }, drawCircle: function(ctx, x, y){ // 画圆函数
ctx.strokeStyle = ‘#FFFFFF’; ctx.lineWidth = 2; ctx.beginPath();
ctx.arc(x, y, this.r, 0, Math.PI * 2, true); ctx.closePath();
ctx.stroke(); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
createCircles: function(){
  var ctx = this.ctx,
    drawCircle = this.drawCircle,
    n = this.n;
  this.r = ctx.canvas.width / (2 + 4 * n) // 这里是参考的,感觉这种画圆的方式挺合理的,方方圆圆
  r = this.r;
  this.circles = []; // 用来存储圆心的位置
  for(var i = 0; i < n; i++){
    for(var j = 0; j < n; j++){
      var p = {
        x: j * 4 * r + 3 * r,
        y: i * 4 * r + 3 * r,
        id: i * 3 + j
      }
      this.circles.push(p);
    }
  }
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // 为了防止重复画
  this.circles.forEach(function(v){
    drawCircle(ctx, v.x, v.y); // 画每个圆
  })
},
 
drawCircle: function(ctx, x, y){ // 画圆函数
  ctx.strokeStyle = ‘#FFFFFF’;
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.arc(x, y, this.r, 0, Math.PI * 2, true);
  ctx.closePath();
  ctx.stroke();
}

画圆函数,须要注意:怎样确定圆的半径和各种圆的圆心坐标(这么些本身是参照的),倘诺以圆心为大旨,各种圆上下左右各伸张一个半径的相距,同时为了防备四边太挤,四周在填充一个半径的离开。那么得到的半径就是
width / ( 4 * n + 2),对应也足以算出逐个圆所在的圆心坐标,也有一套公式,GET

if(x>0)//正着画线是如此的
for(var i=0;i<x;i++){
var height=y/x*i
{

arr = [];

2. 画线

画线需求借助 touch event 来形成,约等于,当大家 touchstart
的时候,传入开端时的相对坐标,作为线的一面,当大家 touchmove
的时候,拿到坐标,作为线的另一面,当大家 touchend 的时候,开头画线。

那只是一个测试画线功用,具体的末尾再开展改动。

有五个函数,得到当前 touch 的绝对坐标:

getTouchPos: function(e){ // 得到触摸点的争执地方 var rect =
e.target.getBoundingClientRect(); var p = { // 相对坐标 x:
e.touches[0].clientX – rect.left, y: e.touches[0].clientY – rect.top
}; return p; }

1
2
3
4
5
6
7
8
getTouchPos: function(e){ // 获得触摸点的相对位置
  var rect = e.target.getBoundingClientRect();
  var p = { // 相对坐标
    x: e.touches[0].clientX – rect.left,
    y: e.touches[0].clientY – rect.top
  };
  return p;
}

画线:

drawLine: function(p1, p2){ // 画线 this.ctx.beginPath();
this.ctx.lineWidth = 3; this.ctx.moveTo(p1.x, p2.y);
this.ctx.lineTo(p.x, p.y); this.ctx.stroke(); this.ctx.closePath(); },

1
2
3
4
5
6
7
8
drawLine: function(p1, p2){ // 画线
  this.ctx.beginPath();
  this.ctx.lineWidth = 3;
  this.ctx.moveTo(p1.x, p2.y);
  this.ctx.lineTo(p.x, p.y);
  this.ctx.stroke();
  this.ctx.closePath();
},

下一场就是监听 canvas 的 touchstarttouchmove、和 touchend 事件了。

frag.appendChild(drawPoint(i+x1,height+y1));
}
}
if(x<0){//有时候是倒着画线的
for(var i=0;i>x;i–){
var height=y/x*i
{
frag.appendChild(this.drawPoint(i+x1,height+y1));
}
}
}//end if

restPoint = [];

3. 画折线

所谓的画折线,就是,将已经触动到的点连起来,可以把它当作是画折线。

率先,要用三个数组,一个数组用于已经 touch 过的点,另一个数组用于存储未
touch 的点,然后在 move 监听时候,对 touch
的相对地方展开判定,假诺触到点,就把该点从未 touch 移到 touch
中,然后,画折线,思路也很简短。

JavaScript

drawLine: function(p){ // 画折线 this.ctx.beginPath();
this.ctx.lineWidth = 3; this.ctx.moveTo(this.touchCircles[0].x,
this.touchCircles[0].y); for (var i = 1 ; i <
this.touchCircles.length ; i++) {
this.ctx.lineTo(this.touchCircles[i].x, this.touchCircles[i].y); }
this.ctx.lineTo(p.x, p.y); this.ctx.stroke(); this.ctx.closePath(); },

1
2
3
4
5
6
7
8
9
10
11
drawLine: function(p){ // 画折线
  this.ctx.beginPath();
  this.ctx.lineWidth = 3;
  this.ctx.moveTo(this.touchCircles[0].x, this.touchCircles[0].y);
  for (var i = 1 ; i < this.touchCircles.length ; i++) {
    this.ctx.lineTo(this.touchCircles[i].x, this.touchCircles[i].y);
  }
  this.ctx.lineTo(p.x, p.y);
  this.ctx.stroke();
  this.ctx.closePath();
},

JavaScript

judgePos: function(p){ // 判断 触点 是否在 circle 內 for(var i = 0; i
< this.restCircles.length; i++){ temp = this.restCircles[i];
if(Math.abs(p.x – temp.x) < r && Math.abs(p.y – temp.y) < r){
this.touchCircles.push(temp); this.restCircles.splice(i, 1);
this.touchFlag = true; break; } } }

1
2
3
4
5
6
7
8
9
10
11
judgePos: function(p){ // 判断 触点 是否在 circle 內
  for(var i = 0; i < this.restCircles.length; i++){
    temp = this.restCircles[i];
    if(Math.abs(p.x – temp.x) < r && Math.abs(p.y – temp.y) < r){
      this.touchCircles.push(temp);
      this.restCircles.splice(i, 1);
      this.touchFlag = true;
      break;
    }
  }
}

}
document.getElementById(this.divId).appendChild(frag);
};
this.drawCircle = function(r, x, y){
//画个圆。x,原点横坐标;y,原点纵坐标;r,半径
var frag=document.createDocumentFragment();
for(var degree=0;degree<360;degree+=2){
var x1=r*Math.sin(degree*Math.PI/180);
var y1=r*Math.cos(degree*Math.PI/180);
frag.appendChild(drawPoint(x+x1,y+y1));
}
document.body.appendChild(frag);
};
this.dragCircle = function(x1,y1,x2,y2){
//拖出一个圆来
var r=Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));//求出半径的长
直角三角形中 斜边的平方=多少个直边的平方之和

r = ctx.canvas.width / (2+4* n);// 公式计算 半径和canvas的轻重有关

4. 标记已画

后面已经说了,大家把早已 touch
的点(圆)放到数组中,这么些时候必要将那几个已经 touch
的点给标记一下,在圆心处画一个小实心圆:

JavaScript

drawPoints: function(){ for (var i = 0 ; i < this.touchCircles.length
; i++) { this.ctx.fillStyle = ‘#FFFFFF’; this.ctx.beginPath();
this.ctx.arc(this.touchCircles[i].x, this.touchCircles[i].y, this.r
/ 2, 0, Math.PI * 2, true); this.ctx.closePath(); this.ctx.fill(); } }

1
2
3
4
5
6
7
8
9
drawPoints: function(){
  for (var i = 0 ; i < this.touchCircles.length ; i++) {
    this.ctx.fillStyle = ‘#FFFFFF’;
    this.ctx.beginPath();
    this.ctx.arc(this.touchCircles[i].x, this.touchCircles[i].y, this.r / 2, 0, Math.PI * 2, true);
    this.ctx.closePath();
    this.ctx.fill();
  }
}

再者加上一个 reset 函数,当 touchend 的时候调用,400ms 调用 reset 重置
canvas。

到后天达成,一个 H5 手势解锁的简易版已经基本做到。

var frag=document.createDocumentFragment();
for(var degree=0;degree<360;degree+=2){//每隔2度画一个点
var x2=r*Math.sin(degree*Math.PI/180);
var y2=r*Math.cos(degree*Math.PI/180);
frag.appendChild(drawPoint(x1+x2,y1+y2));
}
document.getElementById(this.divId).appendChild(frag);
};
this.drawRect = function(startX, startY, lengthX, lengthY, newId,
text){
//(startX, startY)源点坐标,lengthX,长 lengthY,宽 newId,新成立的div的Id
text,div内容
var myDiv=document.createElement(‘div’);
if(newId){
myDiv.id=newId;
}
myDiv.style.width= lengthX + ‘px’;
myDiv.style.height= lengthY + ‘px’;
myDiv.style.backgroundColor = this.color;
myDiv.style.left=startX + ‘px’;
myDiv.style.top=startY + ‘px’;
myDiv.style.textAlign= ‘center’;
if(text){
myDiv.innerHTML = text;
}
document.getElementById(this.divId).appendChild(myDiv);
};
};

for(vari =0; i < n ; i++) {

password

为了要完结记住和重置密码的机能,把 password 保存在 localStorage
中,但首先要丰盛需要的 html 和体制。

window.onload=function(){
var g = new Graphics(‘div1’, ‘red’);
g.drawLine(500,30,0,30);
g.color = ‘#CDC9C9’;
g.drawRect(10,10,200,200, ”, ‘测试’);
}

for(varj =0; j < n ; j++) {

1. 添加 message 和 单选框

为了尽量的使界面简单(越丑越好),直接在 body 后边添加了:

XHTML

<div id=”select”> <div
class=”message”>请输下手势密码</div> <div class=”radio”>
<label><input type=”radio”
name=”pass”>设置手势密码</label> <label><input
type=”radio” name=”pass”>验证手势密码</label> </div>
</div>

1
2
3
4
5
6
7
<div id="select">
  <div class="message">请输入手势密码</div>
  <div class="radio">
    <label><input type="radio" name="pass">设置手势密码</label>
    <label><input type="radio" name="pass">验证手势密码</label>
  </div>
</div>

将助长到 dom 已 option 的款型传给 handLock:

var el = document.getElementById(‘handlock’), info =
el.getElementsByClassName(‘info’)[0], select =
document.getElementById(‘select’), message =
select.getElementsByClassName(‘message’)[0], radio =
select.getElementsByClassName(‘radio’)[0], setPass =
radio.children[0].children[0], checkPass =
radio.children[1].children[0]; new handLock({ el: el, info: info,
message: message, setPass: setPass, checkPass: checkPass, n: 3
}).init();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var el = document.getElementById(‘handlock’),
  info = el.getElementsByClassName(‘info’)[0],
  select = document.getElementById(‘select’),
  message = select.getElementsByClassName(‘message’)[0],
  radio = select.getElementsByClassName(‘radio’)[0],
  setPass = radio.children[0].children[0],
  checkPass = radio.children[1].children[0];
new handLock({
  el: el,
  info: info,
  message: message,
  setPass: setPass,
  checkPass: checkPass,
  n: 3
}).init();

复制…

arr.push({

2. info 音讯突显

至于 info 新闻显示,自个儿写了一个悬浮窗,然后默许为
display: none,然后写了一个 showInfo
函数用来浮现提醒消息,间接调用:

showInfo: function(message, timer){ // 专门用来展示 info var info =
this.dom.info; info.innerHTML = message; info.style.display = ‘block’;
setTimeout(function(){ info.style.display = ”; }, 1000) }

1
2
3
4
5
6
7
8
showInfo: function(message, timer){ // 专门用来显示 info
  var info = this.dom.info;
  info.innerHTML = message;
  info.style.display = ‘block’;
  setTimeout(function(){
    info.style.display = ”;
  }, 1000)
}

关于 info 的样式,在 html 中呢。

x: j *4* r +3* r,

3. 有关密码

先不考虑从 localStorage 读取到情形,新加一个 lsPass
对象,专门用于存储密码,由于密码意况相比较多,比如设置密码,二次认同密码,验证密码,为了方便管理,暂时设置了密码的三种形式,分别是:

model:1 验证密码方式

model:2 装置密码格局

model:3 安装密码二次注明

具体看上面那些图:

皇家赌场手机版 8

这三种 model ,只要处理好它们中间怎么跳转就 ok 了,即状态的变更。

故而就有了 initPass:

initPass: function(){ // 将密码初叶化 this.lsPass =
w.localStorage.getItem(‘HandLockPass’) ? { model: 1, pass:
w.localStorage.getItem(‘HandLockPass’).split(‘-‘) } : { model: 2 };
this.updateMessage(); }, updateMessage: function(){ //
依据当前形式,更新 dom if(this.lsPass.model == 2){
this.dom.setPass.checked = true; this.dom.message.innerHTML =
‘请设置手势密码’; }else if(this.lsPass.model == 1){
this.dom.checkPass.checked = true; this.dom.message.innerHTML =
‘请证实手势密码’; }else if(this.lsPass.model = 3){
this.dom.setPass.checked = true; this.dom.message.innerHTML =
‘请再次输入密码’; } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
initPass: function(){ // 将密码初始化
  this.lsPass = w.localStorage.getItem(‘HandLockPass’) ? {
    model: 1,
    pass: w.localStorage.getItem(‘HandLockPass’).split(‘-‘)
  } : { model: 2 };
  this.updateMessage();
},
 
updateMessage: function(){ // 根据当前模式,更新 dom
  if(this.lsPass.model == 2){
    this.dom.setPass.checked = true;
    this.dom.message.innerHTML = ‘请设置手势密码’;
  }else if(this.lsPass.model == 1){
    this.dom.checkPass.checked = true;
    this.dom.message.innerHTML = ‘请验证手势密码’;
  }else if(this.lsPass.model = 3){
    this.dom.setPass.checked = true;
    this.dom.message.innerHTML = ‘请再次输入密码’;
  }
},

有必不可少再来介绍一下 lsPass 的格式:

this.lsPass = { model:1, // 代表近来的方式 pass: [0, 1, 2, 4, 5] //
代表近期的密码,只怕不存在 }

1
2
3
4
this.lsPass = {
  model:1, // 表示当前的模式
  pass: [0, 1, 2, 4, 5] // 表示当前的密码,可能不存在
}

因为事先早已有了一个骨干的兑现框架,以往只须要在 touchend
之后,写一个函数,功效就是先对脚下的 model
进行判定,完成对应的效应,那里要用到 touchCircles 数组,表示密码的逐一:

JavaScript

checkPass: function(){ var succ, model = this.lsPass.model; //succ
今后会用到 if(model == 2){ // 设置密码 if(this.touchCircles.length <
5){ // 验证密码长度 succ = false; this.showInfo(‘密码长度至少为 5!’,
1000); }else{ succ = true; this.lsPass.temp = []; //
将密码放到临时区存储 for(var i = 0; i < this.touchCircles.length;
i++){ this.lsPass.temp.push(this.touchCircles[i].id); }
this.lsPass.model = 3; this.showInfo(‘请再度输入密码’, 1000);
this.updateMessage(); } }else if(model == 3){// 确认密码 var flag =
true; // 先要验证密码是还是不是科学 if(this.touchCircles.length ==
this.lsPass.temp.length){ var tc = this.touchCircles, lt =
this.lsPass.temp; for(var i = 0; i < tc.length; i++){ if(tc[i].id
!= lt[i]){ flag = false; } } }else{ flag = false; } if(!flag){ succ =
false; this.showInfo(‘一次密码不等同,请重新输入’, 1000);
this.lsPass.model = 2; // 由于密码不得法,重新回来 model 2
this.updateMessage(); }else{ succ = true; // 密码正确,localStorage
存储,并安装处境为 model 1 w.localStorage.setItem(‘HandLockPass’,
this.lsPass.temp.join(‘-‘)); // 存储字符串 this.lsPass.model = 1;
this.lsPass.pass = this.lsPass.temp; this.updateMessage(); } delete
this.lsPass.temp; // 很重大,一定要删掉,bug }else if(model == 1){ //
验证密码 var tc = this.touchCircles, lp = this.lsPass.pass, flag = true;
if(tc.length == lp.length){ for(var i = 0; i < tc.length; i++){
if(tc[i].id != lp[i]){ flag = false; } } }else{ flag = false; }
if(!flag){ succ = false; this.showInfo(‘很不满,密码错误’, 1000); }else{
succ = true; this.showInfo(‘恭喜你,验证通过’, 1000); } } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
checkPass: function(){
  var succ, model = this.lsPass.model; //succ 以后会用到
  if(model == 2){ // 设置密码
    if(this.touchCircles.length < 5){ // 验证密码长度
      succ = false;
      this.showInfo(‘密码长度至少为 5!’, 1000);
    }else{
      succ = true;
      this.lsPass.temp = []; // 将密码放到临时区存储
      for(var i = 0; i < this.touchCircles.length; i++){
        this.lsPass.temp.push(this.touchCircles[i].id);
      }
      this.lsPass.model = 3;
      this.showInfo(‘请再次输入密码’, 1000);
      this.updateMessage();
    }
  }else if(model == 3){// 确认密码
    var flag = true;
    // 先要验证密码是否正确
    if(this.touchCircles.length == this.lsPass.temp.length){
      var tc = this.touchCircles, lt = this.lsPass.temp;
      for(var i = 0; i < tc.length; i++){
        if(tc[i].id != lt[i]){
          flag = false;
        }
      }
    }else{
      flag = false;
    }
    if(!flag){
      succ = false;
      this.showInfo(‘两次密码不一致,请重新输入’, 1000);
      this.lsPass.model = 2; // 由于密码不正确,重新回到 model 2
      this.updateMessage();
    }else{
      succ = true; // 密码正确,localStorage 存储,并设置状态为 model 1
      w.localStorage.setItem(‘HandLockPass’, this.lsPass.temp.join(‘-‘)); // 存储字符串
      this.lsPass.model = 1;
      this.lsPass.pass = this.lsPass.temp;
      this.updateMessage();
    }
    delete this.lsPass.temp; // 很重要,一定要删掉,bug
  }else if(model == 1){ // 验证密码
    var tc = this.touchCircles, lp = this.lsPass.pass, flag = true;
    if(tc.length == lp.length){
      for(var i = 0; i < tc.length; i++){
        if(tc[i].id != lp[i]){
          flag = false;
        }
      }
    }else{
      flag = false;
    }
    if(!flag){
      succ = false;
      this.showInfo(‘很遗憾,密码错误’, 1000);
    }else{
      succ = true;
      this.showInfo(‘恭喜你,验证通过’, 1000);
    }
  }
},

密码的设置要参考前面这张图,要随时警惕状态的更动。

y: i *4* r +3* r

4. 手动重置密码

思路也很粗略,就是添加点击事件,点击之后,改变 model
即可,点击事件如下:

this.dom.setPass.add伊夫ntListener(‘click’, function(e){
self.lsPass.model = 2; // 改变 model 为设置密码 self.updateMessage(); //
更新 message self.showInfo(‘请设置密码’, 1000); })
this.dom.checkPass.add伊夫ntListener(‘click’, function(e){
if(self.lsPass.pass){ self.lsPass.model = 1; self.updateMessage();
self.showInfo(‘请验证密码’, 1000) }else{ self.showInfo(‘请先设置密码’,
1000); self.updateMessage(); } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
this.dom.setPass.addEventListener(‘click’, function(e){
  self.lsPass.model = 2; // 改变 model 为设置密码
  self.updateMessage(); // 更新 message
  self.showInfo(‘请设置密码’, 1000);
})
this.dom.checkPass.addEventListener(‘click’, function(e){
  if(self.lsPass.pass){
    self.lsPass.model = 1;
    self.updateMessage();
    self.showInfo(‘请验证密码’, 1000)
  }else{
    self.showInfo(‘请先设置密码’, 1000);
    self.updateMessage();
  }
})

ps:这几个中还有多少个小的 bug,因为 model 唯有 3
个,所以设置的时候,当点击重置密码的时候,没有设置密码成功,又切成验证密码状态,此时不能提高沿用旧密码,原因是
model 唯有七个

});

5. 添加 touchend 颜色变化

大吉大利这么些差不离就马到成功了,那个作用最首要的是给用户一个指示,若用户划出的密码符合规范,突显浅莲红,若不符合规范或错误,彰显古金色警戒。

因为事先早已安装了一个 succ 变量,专门用来重绘。

JavaScript

drawEndCircles: function(color){ // end 时重绘已经 touch 的圆 for(var i
= 0; i < this.touchCircles.length; i++){
this.drawCircle(this.touchCircles[i].x, this.touchCircles[i].y,
color); } }, // 调用 if(succ){ this.drawEndCircles(‘#2CFF26’); // 绿色
}else{ this.drawEndCircles(‘red’); // 红色 }

1
2
3
4
5
6
7
8
9
10
11
12
drawEndCircles: function(color){ // end 时重绘已经 touch 的圆
  for(var i = 0; i < this.touchCircles.length; i++){
    this.drawCircle(this.touchCircles[i].x, this.touchCircles[i].y, color);
  }
},
 
// 调用
if(succ){
  this.drawEndCircles(‘#2CFF26’); // 绿色
}else{
  this.drawEndCircles(‘red’); // 红色
}

那么,一个足以演示的本子就生成了,就算还存在部分
bug,随后会来解决。(详情分支 password)

restPoint.push({

一些 bugs

有些 bugs 在做的时候就发现了,一些 bug
后来用手机测试的时候才意识,比如,小编用 chrome 的时候,没有察觉这一个bug,当自家用 android 手机 chrome 浏览器测试的时候,发现当本身 touchmove
向下的时候,会触发浏览器的下拉刷新,消除办法:加了一个
preventDefault,没悟出居然成功了。

this.canvas.addEventListener(‘touchmove’, function(e){ e.preventDefault
? e.preventDefault() : null; var p = self.getTouchPos(e);
if(self.touchFlag){ self.update(p); }else{ self.judgePos(p); } }, false)

1
2
3
4
5
6
7
8
9
this.canvas.addEventListener(‘touchmove’, function(e){
  e.preventDefault ? e.preventDefault() : null;
  var p = self.getTouchPos(e);
  if(self.touchFlag){
    self.update(p);
  }else{
    self.judgePos(p);
  }
}, false)

x: j *4* r +3* r,

关于 showInfo

是因为showInfo 中有 setTimeout 函数,可以见到函数里的演出为
1s,导致若是我们操作的速度相比较快,在 1s 内连接 show 了不少个
info,前边的 info 会被首个 info 的 setTimeout 弄乱,展现的时光低于
1s,或更短。比如,当再度点击设置手势密码和表达手势密码,会发出那一个 bug。

化解办法有三个,一个是充实一个专门用来浮现的数组,每一回从数组中取值然后突显。另一种解题思路和防抖动的笔触很像,就是当有一个新的
show 到来时,把在此之前的要命 setTimeout 清除掉。

那里运用第三种思路:

showInfo: function(message, timer){ // 专门用来突显 info
clearTimeout(this.showInfo.timer); var info = this.dom.info;
info.innerHTML = message; info.style.display = ‘block’;
this.showInfo.timer = setTimeout(function(){ info.style.display = ”; },
timer || 1000) },

1
2
3
4
5
6
7
8
9
showInfo: function(message, timer){ // 专门用来显示 info
  clearTimeout(this.showInfo.timer);
  var info = this.dom.info;
  info.innerHTML = message;
  info.style.display = ‘block’;
  this.showInfo.timer = setTimeout(function(){
    info.style.display = ”;
  }, timer || 1000)
},

y: i *4* r +3* r

斩草除根小尾巴

所谓的小尾巴,如下:

皇家赌场手机版 9

化解办法也很粗略,在 touchend 的时候,先进行 clearRect 就 ok 了。

});

有关优化

个性优化向来都以一个大标题,不要觉得前端不须要考虑内存,就能够不管写代码。

事先在计划协调网页的时候,用到了滚动,鼠标滑轮轻轻一碰,滚动函数就执行了几十多则几百次,从前也考虑过化解办法。

}

优化 canvas 部分

对于 touchmove 函数,原理都是均等的,手指一划,就举办了 n
数十次,那个题材背后在消除,先来看另一个标题。

touchmove
是一个往往函数,看到这里,假若你并不曾仔细看本人的代码,那你对自己动用的
canvas 画图格局可能不太了然,上面那几个是 touchmove 函数干了如何事:

  1. 先判断,假如当前处在未当选一个密码状态,则继续监视当前的职位,直到选中第二个密码,进入第二步;
  2. 跻身 update 函数,update
    函数根本干四件事,重绘圆(密码)、判断当前岗位、重绘点、重绘线;

其次步是一个很担心的动作,为何老是都要重绘圆,点和线呢?

皇家赌场手机版 10

地点这些图可以很好的阐明难题,因为在设置或表达密码的进度中,我们须求用一条线来连接触点到当前的结尾一个密码,并且当
touchmove 的时候,能看到它们在变化。那一个效应很棒,可以描绘出 touchmove
的轨迹。

不过,那就不大概不要时时刷新 canvas,质量大大地降落,刷新的那可是所有
canvas。

因为 canvas
唯有一个,既要画背景圆(密码),又要画已选密码的点,和折线。这些中许多步骤,自始至终只必要五回就好了,比如背景圆,只需在开行的时候画一遍,已选密码,只要当
touchCircles
新新币素的时候才会用一遍,还不用重绘,只要画就可以了。折线分成两部分,一部分是已选密码之间的连线,还有就是最后一个密码点到当前触点之间的连线。

假若有两个 canvas 就好了,一个存储静态的,一个尤其用于重绘

为何不可以有吧!

自小编的缓解思路是,以往有多个canvas,一个在尾部,作为描绘静态的圆、点和折线,另一个在上层,一方面监听
touchmove
事件,另一方面不停地重绘最终一个密码点的圆心到当下触点之间的线。要是那样可以的话,touchmove
函数执行两次的频率大大升高。

插入第三个 canvas:

var canvas2 = canvas.cloneNode(canvas, true); canvas2.style.position =
‘absolute’;//让上层 canvas 覆盖底层 canvas canvas2.style.top = ‘0’;
canvas2.style.left = ‘0’; this.el.appendChild(canvas2); this.ctx2 =
canvas2.getContext(‘2d’);

1
2
3
4
5
6
var canvas2 = canvas.cloneNode(canvas, true);
canvas2.style.position = ‘absolute’;//让上层 canvas 覆盖底层 canvas
canvas2.style.top = ‘0’;
canvas2.style.left = ‘0’;
this.el.appendChild(canvas2);
this.ctx2 = canvas2.getContext(‘2d’);

要转移对第三个 ctx2 举行 touch 监听,并安装一个 this.reDraw
参数,表示有新的密码添加进去,须要对点和折线添加新内容, update
函数要改成这么:

update: function(p){ // 更新 touchmove this.judgePos(p); // 每一回都要看清
this.drawLine2TouchPos(p); //
新加函数,用于绘末了一个密码点点圆心到触点之间的线 if(this.reDraw){ //
有新的密码加进来 this.reDraw = false; this.drawPoints(); // 添加新点
this.drawLine();// 添加新线 } },

1
2
3
4
5
6
7
8
9
update: function(p){ // 更新 touchmove
  this.judgePos(p); // 每次都要判断
  this.drawLine2TouchPos(p); // 新加函数,用于绘最后一个密码点点圆心到触点之间的线
  if(this.reDraw){ // 有新的密码加进来
    this.reDraw = false;
    this.drawPoints(); // 添加新点
    this.drawLine();// 添加新线
  }
},

drawLine2TouchPos: function(p){ var len = this.touchCircles.length;
if(len >= 1){ this.ctx2.clearRect(0, 0, this.width, this.width); //
先清空 this.ctx2.beginPath(); this.ctx2.lineWidth = 3;
this.ctx2.moveTo(this.touchCircles[len – 1].x, this.touchCircles[len

  • 1].y); this.ctx2.lineTo(p.x, p.y); this.ctx2.stroke();
    this.ctx2.closePath(); } },
1
2
3
4
5
6
7
8
9
10
11
12
drawLine2TouchPos: function(p){
  var len = this.touchCircles.length;
  if(len >= 1){
    this.ctx2.clearRect(0, 0, this.width, this.width); // 先清空
    this.ctx2.beginPath();
    this.ctx2.lineWidth = 3;
    this.ctx2.moveTo(this.touchCircles[len – 1].x, this.touchCircles[len – 1].y);
    this.ctx2.lineTo(p.x, p.y);
    this.ctx2.stroke();
    this.ctx2.closePath();
  }
},

相应的 drawPoints 和 drawLine
函数也要对应修改,由原理画所有的,到后天只要求画新加的。

功能怎么着:

皇家赌场手机版 11

move 函数执行数次,而任何函数只有当新密码加进来的时候才实施一回。

}

参与节流函数

事先也一度说过了,这些 touchmove
函数执行的次数相比较多,固然大家早已用多个 canvas 对重绘做了很大的优化,但
touchmove 依然有点大开发。

本条时候小编想开了防抖动和节流,首先防抖动肯定是老大的,万一自个儿一向处在
touch
状态,重绘会延迟死的,那么些时候节流会好有的。防抖和节流。

先写一个节流函数:

throttle: function(func, delay, mustRun){ var timer, startTime = new
Date(), self = this; return function(){ var curTime = new Date(), args =
arguments; clearTimeout(timer); if(curTime – startTime >= mustRun){
startTime = curTime; func.apply(self, args); }else{ timer =
setTimeout(function(){ func.apply(self, args); }, delay) } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
throttle: function(func, delay, mustRun){
  var timer, startTime = new Date(), self = this;
  return function(){
    var curTime = new Date(), args = arguments;
    clearTimeout(timer);
    if(curTime – startTime >= mustRun){
      startTime = curTime;
      func.apply(self, args);
    }else{
      timer = setTimeout(function(){
        func.apply(self, args);
      }, delay)
    }
  }
}

节流函数的情趣:在延迟为 delay
的年华内,假若函数再一次接触,则重新计时,这些效应和防抖动是千篇一律的,第多少个参数
mustRun 是一个岁月距离,表示在岁月间隔大于 mustRun
后的一个函数可以立即直接执行。

下一场对 touchmove 的回调函数举行改建:

var t = this.throttle(function(e){ e.preventDefault ? e.preventDefault()
: null; e.stopPropagation ? e.stopPropagation() : null; var p =
this.getTouchPos(e); if(this.touchFlag){ this.update(p); }else{
this.judgePos(p); } }, 16, 16)
this.canvas2.addEventListener(‘touchmove’, t, false)

1
2
3
4
5
6
7
8
9
10
11
var t = this.throttle(function(e){
  e.preventDefault ? e.preventDefault() : null;
  e.stopPropagation ? e.stopPropagation() : null;
  var p = this.getTouchPos(e);
  if(this.touchFlag){
    this.update(p);
  }else{
    this.judgePos(p);
  }
}, 16, 16)
this.canvas2.addEventListener(‘touchmove’, t, false)

有关 delay 和 mustRun 的大运距离难点,web 品质里有一个 16ms
的概念,就是说如若要完毕每秒 60 帧,间隔为 1000/60 大致为 16
ms。假诺距离大于 16ms 则 fps 会比 60 低。

鉴于此,大家那里将 delay 和 mustRun 都设为
16,在最好的图景下,相当于最坏的图景下,恐怕需求 15 + 15 = 30ms
才会履行三次,那一个时候要设置多少个 8
才创制,然则考虑到手指运动是一个连连的进程,怎么只怕会每 15
秒执行五次,经过在线测试,发现安装成 16 效果还不易。

质量真的能优化吗,我们来看八个图片,do 和 wantdo
表示真实执行和放手节流函数中排队准备实施。

当 touchmove 速度一般或飞跃的时候:

皇家赌场手机版 12

当 touchmove 速度很慢的时候:

皇家赌场手机版 13

可以看出来,滑动进程中,速度一般和高速,平均优化了一半,慢速效果也优化了
20 到 30%
之间,平日手势锁解锁时候,肯定速度很快。可知,节流的优化仍然很显明的。

重倘若,优化将来的流程性,没有受到任何影响。

本条节流函数最终照旧出现了一个 bug:由于是延迟执行的,导致
e.preventDefault
失效,在手机浏览器向下滑会现出刷新的场馆,那也算事件延迟的一个残害吗。

消除办法:在节流函数提前撤废专擅认同事件:

throttle: function(func, delay, mustRun){ var timer, startTime = new
Date(), self = this; return function(e){ if(e){ e.preventDefault ?
e.preventDefault() : null; //提前撤销暗许事件,不要等到 setTimeout
e.stopPropagation ? e.stopPropagation() : null; } … } }

1
2
3
4
5
6
7
8
9
10
throttle: function(func, delay, mustRun){
  var timer, startTime = new Date(), self = this;
  return function(e){
    if(e){
      e.preventDefault ? e.preventDefault() : null; //提前取消默认事件,不要等到 setTimeout
      e.stopPropagation ? e.stopPropagation() : null;
    }
    …
  }
}

//return arr;

总结

大致花了三天左右的年华,将那一个 H5
的手势解锁给完了,本人仍然相比较满足的,即使或然达不到评判老师的肯定,可是本身在做的长河中,学习到了很多新知识。

}

参考

H5lock
Canvas教程
js获取单选框里面的值
前端高质量滚动 scroll
及页面渲染优化

3 赞 5 收藏
评论

皇家赌场手机版 14

canvas里的圆形画好之后可以展开事件绑定

functionbindEvent(){

can.addEventListener(“touchstart”,function(e){

varpo = getPosition(e);

console.log(po);

for(vari =0; i < arr.length ; i++) {

if(Math.abs(po.x – arr[i].x) < r &&Math.abs(po.y – arr[i].y) <
r) {// 用来判断初阶点是不是在规模内部

touchFlag =true;

drawPoint(arr[i].x,arr[i].y);

lastPoint.push(arr[i]);

restPoint.splice(i,1);

break;

}

}

},false);

can.addEventListener(“touchmove”,function(e){

if(touchFlag) {

update(getPosition(e));

}

},false);

can.addEventListener(“touchend”,function(e){

if(touchFlag) {

touchFlag =false;

storePass(lastPoint);

setTimeout(function(){

init();

},300);

}

},false);

}

继之到了最根本的步子绘制解锁路径逻辑,通过touchmove事件的接踵而来触发,调用canvas的moveTo方法和lineTo方法来画出折现,同时判断是不是达标大家所画的范畴里面,其中lastPoint保存不易的规模路径,restPoint保存全体圈圈去除正确路线之后剩余的。
Update方法:

functionupdate(po){// 主旨转移方式在touchmove时候调用

ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);

for(vari =0; i < arr.length ; i++) {// 每帧先把面板画出来

drawCle(arr[i].x, arr[i].y);

}

drawPoint(lastPoint);// 每帧花轨迹

drawLine(po , lastPoint);// 每帧画圆心

for(vari =0; i < restPoint.length ; i++) {

if(Math.abs(po.x – restPoint[i].x) < r &&Math.abs(po.y –
restPoint[i].y) < r) {

drawPoint(restPoint[i].x, restPoint[i].y);

lastPoint.push(restPoint[i]);

restPoint.splice(i,1);

break;

}

}

}

最终就是截止工作,把路子里面的lastPoint保存的数组变成密码存在localstorage里面,之后就用来拍卖解锁验证逻辑了

functionstorePass(psw){// touchend停止之后对密码和意况的拍卖

if(pswObj.step ==1) {

if(checkPass(pswObj.fpassword, psw)) {

pswObj.step =2;

pswObj.spassword = psw;

document.getElementById(‘title’).innerHTML =’密码保存成功’;

drawStatusPoint(‘#2CFF26’);

window.localStorage.setItem(‘passwordx’,JSON.stringify(pswObj.spassword));

window.localStorage.setItem(‘chooseType’, chooseType);

}else{

document.getElementById(‘title’).innerHTML =’两遍差异等,重新输入’;

drawStatusPoint(‘red’);

deletepswObj.step;

}

}elseif(pswObj.step ==2) {

if(checkPass(pswObj.spassword, psw)) {

document.getElementById(‘title’).innerHTML =’解锁成功’;

drawStatusPoint(‘#2CFF26’);

}else{

drawStatusPoint(‘red’);

document.getElementById(‘title’).innerHTML =’解锁战败’;

}

}else{

pswObj.step =1;

pswObj.fpassword = psw;

document.getElementById(‘title’).innerHTML =’再一次输入’;

}

}

Leave a Comment.