菜单

HTML5落到实处荧屏手势解锁

2019年4月17日 - 金沙前端

H五 手势解锁

扫码在线查看:

图片 1

依然点击查阅手机版。

项目 GitHub
地址,H5HandLock。

首先,笔者要证惠氏(WYETH)(Dumex)下,对于这么些项目,笔者是参考别人的,H5lock。

自家以为2个比较客观的解法应该是利用 canvas 来贯彻,不掌握有未有大神用 css
来达成。要是纯用 css 的话,能够将连线先安装
display: none,当手指划过的时候,显示出来。光设置这个本该就不行麻烦呢。

后面领会过 canvas,但从不真的的写过,上面就来介绍自身这几天学习 canvas
并落到实处 H五 手势解锁的长河。

HTML伍达成荧屏手势解锁

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

初稿出处:
AlloyTeam   

作用展现

图片 2

贯彻原理 利用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 == 一) { if (checkPass(pswObj.fpassword, psw)) { pswObj.step
= 二; pswObj.spassword = psw; document.getElementById(‘title’).innerHTML
= ‘密码保存成功’; drawStatusPoint(‘#2CFF二陆’);
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 ==
二) { if (checkPass(pswObj.spassword, psw)) {
document.getElementById(‘title’).innerHTML = ‘解锁成功’;
drawStatusPoint(‘#2CFF贰陆’); } 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解锁写成了1个零部件,放在

2维码体验: 图片 3

 

参考资料:

1 赞 4 收藏 1
评论

图片 4

var ww,wh;

下一场自身将对info进行遍历 创制图片对象. 完结图片预加载.

四. 标识已画

前边已经说了,大家把早已 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。

到今后结束,贰个 H伍 手势解锁的简易版已经主导做到。

<script>
var canvas = document.querySelector(“canvas”),
ctx = canvas.getContext(“2d”);

明天因为太晚了,实在扛不住了,代码有个别地点得到未有解释到位,
笔者先分享给大家. 后续作者会更新的. 多谢各位观众老爷的读书,如相当请赐教,
内裤谢谢不尽. 谢谢我们啦~~~~

伍. 加多 touchend 颜色变化

完毕这一个差不多就马到成功了,那一个成效最关键的是给用户三个升迁,若用户划出的密码符合规范,展现天蓝,若不符合规范或不当,显示茶色警戒。

因为前边早已设置了1个 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)

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Happy Valentine’s Day everyone !</title>
</head>
<style>
body{
overflow: hidden;
margin: 0;
}
h1{
position: fixed;
top: 50%;
left: 0;
width: 100%;
text-align: center;
transform:translateY(-50%);
font-family: ‘Love Ya Like A Sister’, cursive;
font-size: 40px;
color: #c70012;
padding: 0 20px;
}
@media (min-width:1200px){
h1{
font-size: 60px;
}
}
</style>
<body>
<canvas></canvas>
<h1>canvas heart</h1>

<canvas id = “canvas” width = “375” height =
“627”></canvas>

一. 学习 canvas 并消除画圆

MDN
上边有个大概的教程,大约浏览了一下,认为还行。Canvas教程。

先成立3个 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 * 三 + 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

function onResize(){
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
}
ctx.strokeStyle = “red”;
ctx.shadowBlur = 25;
ctx.shadowColor = “hsla(0, 100%, 60%,0.5)”;
var precision = 100;
var hearts = [];
var mouseMoved = false;
function onMove(e){
mouseMoved = true;
if(e.type === “touchmove”){
hearts.push(new Heart(e.touches[0].clientX,
e.touches[0].clientY));
hearts.push(new Heart(e.touches[0].clientX,
e.touches[0].clientY));
}
else{
hearts.push(new Heart(e.clientX, e.clientY));
hearts.push(new Heart(e.clientX, e.clientY));
}
}
var Heart = function(x,y){
this.x = x || Math.random()*ww;
this.y = y || Math.random()*wh;
this.size = Math.random()*2 + 1;
this.shadowBlur = Math.random() * 10;
this.speedX = (Math.random()+0.2-0.6) * 8;
this.speedY = (Math.random()+0.2-0.6) * 8;
this.speedSize = Math.random()*0.05 + 0.01;
this.opacity = 1;
this.vertices = [];
for (var i = 0; i < precision; i++) {
var step = (i / precision – 0.5) * (Math.PI * 2);
var vector = {
x : (15 * Math.pow(Math.sin(step), 3)),
y : -(13 * Math.cos(step) – 5 * Math.cos(2 * step) – 2 * Math.cos(3
* step) – Math.cos(4 * step))
}
this.vertices.push(vector);
}
}
Heart.prototype.draw = function(){
this.size -= this.speedSize;
this.x += this.speedX;
this.y += this.speedY;
ctx.save();
ctx.translate(-1000,this.y);
ctx.scale(this.size, this.size);
ctx.beginPath();
for (var i = 0; i < precision; i++) {
var vector = this.vertices[i];
ctx.lineTo(vector.x, vector.y);
}
ctx.globalAlpha = this.size;
ctx.shadowBlur = Math.round((3 – this.size) * 10);
ctx.shadowColor = “hsla(0, 100%, 60%,0.5)”;
ctx.shadowOffsetX = this.x + 1000;
ctx.globalCompositeOperation = “screen”
ctx.closePath();
ctx.fill()
ctx.restore();
};


不留余地小尾巴

所谓的小尾巴,如下:

图片 5

消除办法也很简短,在 touchend 的时候,先进行 clearRect 就 ok 了。

function render(a){
requestAnimationFrame(render);

function loading(info,callbock){

//图片总个数

var allimg = 0;

for(key in info){

    allimg++;

  }

}

参考

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

3 赞 5 收藏
评论

图片 6

hearts.push(new Heart())
ctx.clearRect(0,0,ww,wh);
for (var i = 0; i < hearts.length; i++) {
hearts[i].draw();
if(hearts[i].size <= 0){
hearts.splice(i,1);
i–;
}
}
}
onResize();
window.addEventListener(“mousemove”, onMove);
window.addEventListener(“touchmove”, onMove);
window.addEventListener(“resize”, onResize);
requestAnimationFrame(render);
</script>
</body>
</html>

//创造键值对图纸路线

var info = {

“background”:”img/background.png”, //背景图片

“plane”: “img/plane.png”, //飞机图片

};

//加载图片财富

loading(info,{

done:main

});

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图