HTML5实现屏幕手势解锁(转载)

来源:https://github.com/lvming6816077/H5lock
http://threejs.org/examples/
http://www.inf.usi.ch/phd/wettel/codecity-download.html (JSCity:把源码可视化成建筑物的 JS 库)
http://www.alloyteam.com/2015/07/html5-shi-xian-ping-mu-shou-shi-jie-suo/ (Web前端 腾讯AlloyTeam Blog )
http://top.jobbole.com/22960/(JSCity:把源码可视化成建筑物的 JS 库)

JS:

(function(){
        window.H5lock = function(obj){
            this.height = obj.height;
            this.width = obj.width;
            this.chooseType = Number(window.localStorage.getItem(‘chooseType‘)) || obj.chooseType;
        };

        H5lock.prototype.drawCle = function(x, y) { // 初始化解锁密码面板
            this.ctx.strokeStyle = ‘#CFE6FF‘;
            this.ctx.lineWidth = 2;
            this.ctx.beginPath();
            this.ctx.arc(x, y, this.r, 0, Math.PI * 2, true);
            this.ctx.closePath();
            this.ctx.stroke();
        }
        H5lock.prototype.drawPoint = function() { // 初始化圆心
            for (var i = 0 ; i < this.lastPoint.length ; i++) {
                this.ctx.fillStyle = ‘#CFE6FF‘;
                this.ctx.beginPath();
                this.ctx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.r / 2, 0, Math.PI * 2, true);
                this.ctx.closePath();
                this.ctx.fill();
            }
        }
        H5lock.prototype.drawStatusPoint = function(type) { // 初始化状态线条
            for (var i = 0 ; i < this.lastPoint.length ; i++) {
                this.ctx.strokeStyle = type;
                this.ctx.beginPath();
                this.ctx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.r, 0, Math.PI * 2, true);
                this.ctx.closePath();
                this.ctx.stroke();
            }
        }
        H5lock.prototype.drawLine = function(po, lastPoint) {// 解锁轨迹
            this.ctx.beginPath();
            this.ctx.lineWidth = 3;
            this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);
            console.log(this.lastPoint.length);
            for (var i = 1 ; i < this.lastPoint.length ; i++) {
                this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
            }
            this.ctx.lineTo(po.x, po.y);
            this.ctx.stroke();
            this.ctx.closePath();

        }
        H5lock.prototype.createCircle = function() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径

            var n = this.chooseType;
            var count = 0;
            this.r = this.ctx.canvas.width / (2 + 4 * n);// 公式计算
            this.lastPoint = [];
            this.arr = [];
            this.restPoint = [];
            var r = this.r;
            for (var i = 0 ; i < n ; i++) {
                for (var j = 0 ; j < n ; j++) {
                    count++;
                    var obj = {
                        x: j * 4 * r + 3 * r,
                        y: i * 4 * r + 3 * r,
                        index: count
                    };
                    this.arr.push(obj);
                    this.restPoint.push(obj);
                }
            }
            this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
            for (var i = 0 ; i < this.arr.length ; i++) {
                this.drawCle(this.arr[i].x, this.arr[i].y);
            }
            //return arr;
        }
        H5lock.prototype.getPosition = function(e) {// 获取touch点相对于canvas的坐标
            var rect = e.currentTarget.getBoundingClientRect();
            var po = {
                x: e.touches[0].clientX - rect.left,
                y: e.touches[0].clientY - rect.top
              };
            return po;
        }
        H5lock.prototype.update = function(po) {// 核心变换方法在touchmove时候调用
            this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);

            for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
                this.drawCle(this.arr[i].x, this.arr[i].y);
            }

            this.drawPoint(this.lastPoint);// 每帧花轨迹
            this.drawLine(po , this.lastPoint);// 每帧画圆心

            for (var i = 0 ; i < this.restPoint.length ; i++) {
                if (Math.abs(po.x - this.restPoint[i].x) < this.r && Math.abs(po.y - this.restPoint[i].y) < this.r) {
                    this.drawPoint(this.restPoint[i].x, this.restPoint[i].y);
                    this.lastPoint.push(this.restPoint[i]);
                    this.restPoint.splice(i, 1);
                    break;
                }
            }

        }
        H5lock.prototype.checkPass = function(psw1, psw2) {// 检测密码
            var p1 = ‘‘,
            p2 = ‘‘;
            for (var i = 0 ; i < psw1.length ; i++) {
                p1 += psw1[i].index + psw1[i].index;
            }
            for (var i = 0 ; i < psw2.length ; i++) {
                p2 += psw2[i].index + psw2[i].index;
            }
            return p1 === p2;
        }
        H5lock.prototype.storePass = function(psw) {// touchend结束之后对密码和状态的处理
            if (this.pswObj.step == 1) {
                if (this.checkPass(this.pswObj.fpassword, psw)) {
                    this.pswObj.step = 2;
                    this.pswObj.spassword = psw;
                    document.getElementById(‘title‘).innerHTML = ‘密码保存成功‘;
                    this.drawStatusPoint(‘#2CFF26‘);
                    window.localStorage.setItem(‘passwordxx‘, JSON.stringify(this.pswObj.spassword));
                    window.localStorage.setItem(‘chooseType‘, this.chooseType);
                } else {
                    document.getElementById(‘title‘).innerHTML = ‘两次不一致,重新输入‘;
                    this.drawStatusPoint(‘red‘);
                    delete this.pswObj.step;
                }
            } else if (this.pswObj.step == 2) {
                if (this.checkPass(this.pswObj.spassword, psw)) {
                    document.getElementById(‘title‘).innerHTML = ‘解锁成功‘;
                    this.drawStatusPoint(‘#2CFF26‘);
                } else {
                    this.drawStatusPoint(‘red‘);
                    document.getElementById(‘title‘).innerHTML = ‘解锁失败‘;
                }
            } else {
                this.pswObj.step = 1;
                this.pswObj.fpassword = psw;
                document.getElementById(‘title‘).innerHTML = ‘再次输入‘;
            }

        }
        H5lock.prototype.makeState = function() {
            if (this.pswObj.step == 2) {
                document.getElementById(‘updatePassword‘).style.display = ‘block‘;
                //document.getElementById(‘chooseType‘).style.display = ‘none‘;
                document.getElementById(‘title‘).innerHTML = ‘请解锁‘;
            } else if (this.pswObj.step == 1) {
                //document.getElementById(‘chooseType‘).style.display = ‘none‘;
                document.getElementById(‘updatePassword‘).style.display = ‘none‘;
            } else {
                document.getElementById(‘updatePassword‘).style.display = ‘none‘;
                //document.getElementById(‘chooseType‘).style.display = ‘block‘;
            }
        }
        H5lock.prototype.setChooseType = function(type){
            chooseType = type;
            init();
        }
        H5lock.prototype.updatePassword = function(){
            window.localStorage.removeItem(‘passwordxx‘);
            window.localStorage.removeItem(‘chooseType‘);
            this.pswObj = {};
            document.getElementById(‘title‘).innerHTML = ‘绘制解锁图案‘;
            this.reset();
        }
        H5lock.prototype.initDom = function(){
            var wrap = document.createElement(‘div‘);
            var str = ‘<h4 id="title" class="title">绘制解锁图案</h4>‘+
                      ‘<a id="updatePassword" style="position: absolute;right: 5px;top: 5px;color:#fff;font-size: 10px;display:none;">重置密码</a>‘+
                      ‘<canvas id="canvas" width="300" height="300" style="background-color: #305066;display: inline-block;margin-top: 15px;"></canvas>‘;
            wrap.setAttribute(‘style‘,‘position: absolute;top:0;left:0;right:0;bottom:0;‘);
            wrap.innerHTML = str;
            document.body.appendChild(wrap);
        }
        H5lock.prototype.init = function() {
            this.initDom();
            this.pswObj = window.localStorage.getItem(‘passwordxx‘) ? {
                step: 2,
                spassword: JSON.parse(window.localStorage.getItem(‘passwordxx‘))
            } : {};
            this.lastPoint = [];
            this.makeState();
            this.touchFlag = false;
            this.canvas = document.getElementById(‘canvas‘);
            this.ctx = this.canvas.getContext(‘2d‘);
            this.createCircle();
            this.bindEvent();
        }
        H5lock.prototype.reset = function() {
            this.makeState();
            this.createCircle();
        }
        H5lock.prototype.bindEvent = function() {
            var self = this;
            this.canvas.addEventListener("touchstart", function (e) {
                e.preventDefault();// 某些android 的 touchmove不宜触发 所以增加此行代码
                 var po = self.getPosition(e);
                 console.log(po);
                 for (var i = 0 ; i < self.arr.length ; i++) {
                    if (Math.abs(po.x - self.arr[i].x) < self.r && Math.abs(po.y - self.arr[i].y) < self.r) {

                        self.touchFlag = true;
                        self.drawPoint(self.arr[i].x,self.arr[i].y);
                        self.lastPoint.push(self.arr[i]);
                        self.restPoint.splice(i,1);
                        break;
                    }
                 }
             }, false);
             this.canvas.addEventListener("touchmove", function (e) {
                if (self.touchFlag) {
                    self.update(self.getPosition(e));
                }
             }, false);
             this.canvas.addEventListener("touchend", function (e) {
                 if (self.touchFlag) {
                     self.touchFlag = false;
                     self.storePass(self.lastPoint);
                     setTimeout(function(){

                        self.reset();
                    }, 300);
                 }

             }, false);
             document.addEventListener(‘touchmove‘, function(e){
                e.preventDefault();
             },false);
             document.getElementById(‘updatePassword‘).addEventListener(‘click‘, function(){
                 self.updatePassword();
              });
        }
})();

  HTML5:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>H5lock</title>
    <style type="text/css">
        body {
            text-align: center;
            background-color: #305066;
        }
        .title {
            color: #22C3AA;
        }
    </style>

    </head>
<body>
<script type="text/javascript" src="javascripts/H5lock.js"></script>
<script type="text/javascript">
//http://www.nihaoshijie.com.cn/index.php/archives/537http://www.nihaoshijie.com.cn/index.php/archives/537
 /*
http://top.jobbole.com/22960/
 http://threejs.org/examples/
http://www.inf.usi.ch/phd/wettel/codecity-download.html
https://github.com/lvming6816077/H5lock
http://www.alloyteam.com/2015/07/html5-shi-xian-ping-mu-shou-shi-jie-suo/
 */
new H5lock({
    chooseType: 3
}).init();
</script>
</body>
</html>

  

时间: 2024-08-30 17:23:31

HTML5实现屏幕手势解锁(转载)的相关文章

HTML5实现屏幕手势解锁

HTML5实现屏幕手势解锁(转载) https://github.com/lvming6816077/H5lockHow to use? <script type="text/javascript" src="src/H5lock.publish.js">var opt = { chooseType: 3, // 3 , 4 , 5, width: 300, // lock wrap width height: 300, // lock wrap hei

(素材源码)猫猫学IOS(三十五)UI之Quartz2D仿真支付宝手势解锁_代理获得密码。

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 源码:http://download.csdn.net/detail/u013357243/8669765 效果: 代码: NYLockView.h // // NYLockView.h // 手势解锁 // // Created by apple on 15-5-6. // Copyright (c) 2015年 znyca

UI进阶--Quartz2D和触摸事件的简单使用:手势解锁

需求:实现一个简易的手势解锁应用,具体效果如下图所示: 实现步骤: 1.代码创建界面,自定义一个view,设置view的背景,颜色等属性: 2.在自定义的view中,定义2个属性,一个是存储被选中按钮的可变数组,另外一个是最后的触摸点(CGPoint); 3.重写initWithFrame方法,在这里,自定义一个方法给initWithFrame方法调用即可,这个自定义的方法里,初始化9个按钮,设置每个按钮的tag,正常状态下的图片以及选中状态的图片,并设置和用户的交互为NO: 4.在自定义的vi

iOS开发UI篇—实现一个简单的手势解锁应用(完善)

iOS开发UI篇—实现一个简单的手势解锁应用(完善) 一.需要实现的效果 二.应用完善 1.绘制不处于按钮范围内的连线 2.解决bug(完善) bug1:如果在began方法中通知view绘图,那么会产生bug.因为,当前点没有清空,在手指移开之后要清空当前点.可以在绘制前进行判断,如果当前点是(0,0)那么就不划线.或者在began方法中不进行重绘. bug2:无限菊花.自定义view的背景色为默认的(黑色),只要重写了drawrect方法,view默认的背景颜色就是黑色的,因为上下文默认的颜

Swift实现手势解锁&amp;界面跳转&amp;读取SQLite数据库

按钮是根据屏幕大小自动布局,所以不会因为设备不同导致错位 数据库操作是GitHub上的SQLiteDB 下面是Storyboard的设计图 下面是实现的代码 // // ViewController.swift // // // Created by XWJACK on 15/12/15. // Copyright © 2015年 XWJACK. All rights reserved. // import UIKit class ViewController: UIViewController

Android进阶之自定义View实战(二)九宫格手势解锁实现

一.引言 在上篇博客Android进阶之自定义View实战(一)仿iOS UISwitch控件实现中我们主要介绍了自定义View的最基本的实现方法.作为自定义View的入门篇,仅仅介绍了Canvas的基本使用方法,而对用户交互层面仅仅处理了单击事件接口,在实际的业务中,常常涉及到手势操作,本篇博客以九宫格手势解锁View为例,来说明自定义View如何根据需求处理用户的手势操作.虽然九宫格手势解锁自定义View网上资料有很多,实现原理大同小异,但这里我只是根据自己觉得最优的思路来实现它,目的是让更

九点(九宫格)式手势解锁自定义view

周末闲着没事,写了个手势解锁的view,实现起来也蛮快的,半天多一点时间就完事.把源码和资源贴出来,给大家分享,希望对大家有用. 效果,就跟手机上的九点手势解锁一样,上个图吧: 过程嘛感觉确实没啥好讲的了,涉及的知识以前的博客都说过了,无非就是canva,paint,touch事件这些,画画圆圈画画线条,剩下的就是细节处理逻辑了.都在代码里,所以这里就主要是贴资源吧. 这个自定义view就一个类,源码如下: package com.cc.library.view; import android.

iOS开发之手势解锁

本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现.事例效果如下所示. 首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程: 1.加载九宫格页面 2.实现按钮被点击及滑动过程中按钮状态的改变 3.实现滑动过程中的连线 4.绘制完毕后判定密码是否正确, 5.密码判定后实现跳转. 下面我们就来用代码实现上述五个过程. 1.加载九宫格界面 1.1九宫格内控件的分布 3*3 ,我们可以自定义view(包含3*3个按钮),添加到viewContr

【iOS开发之旅】手势解锁

BOERLockView.h // // BOERLockView.h // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import <UIKit/UIKit.h> @class BOERLockView; @protocol BOERLockViewDelegate <NSObject> // 结束手势解锁代理事件