手势解锁是app上常见的解锁方式,相比输入密码方式操作起来要方便许多。下面展示如何基于微信小程序实现手机解锁。最终实现效果如下图:

微信小程序开发实例(手势解锁)

  整个功能基于canvas实现,首先添加画布组件,并设定样式

XML/HTML代码
  1. <!--index.wxml-->  
  2. <view class="container">  
  3.   <canvas canvas-id="id-gesture-lock" class="gesture-lock" bindtouchstart="onTouchStart"  
  4.     bindtouchmove="onTouchMove" bindtouchend="onTouchEnd"></canvas>  
  5. </view>  
  6.   
  7. .gesture-lock {  
  8.     margin: 100rpx auto;  
  9.     width: 300px;  
  10.     height: 300px;  
  11.     background-color: #ffffff;  
  12. }  

  手势解锁实现代码在gesture_lock.js中(完整源码地址见末尾)。

  初始化

JavaScript代码
  1. constructor(canvasid, context, cb, opt){  
  2.     this.touchPoints = [];  
  3.     this.checkPoints = [];  
  4.     this.canvasid = canvasid;  
  5.     this.ctx = context;  
  6.     this.width = opt && opt.width || 300; //画布长度  
  7.     this.height = opt && opt.height || 300; //画布宽度  
  8.     this.cycleNum = opt && opt.cycleNum || 3;  
  9.     this.radius = 0;  //触摸点半径  
  10.     this.isParamOk = false;  
  11.     this.marge = this.margeCircle = 25; //触摸点及触摸点和画布边界间隔  
  12.     this.initColor = opt && opt.initColor || '#C5C5C3';     
  13.     this.checkColor = opt && opt.checkColor || '#5AA9EC';  
  14.     this.errorColor = opt && opt.errorColor || '#e19984';  
  15.     this.touchState = "unTouch";  
  16.     this.checkParam();  
  17.     this.lastCheckPoint = null;  
  18.     if (this.isParamOk) {  
  19.         // 计算触摸点的半径长度  
  20.         this.radius = (this.width - this.marge * 2 - (this.margeCircle * (this.cycleNum - 1))) / (this.cycleNum * 2)  
  21.         this.radius = Math.floor(this.radius);  
  22.         // 计算每个触摸点的圆心位置  
  23.         this.calCircleParams();  
  24.     }  
  25.     this.onEnd = cb; //滑动手势结束时的回调函数  
  26. }  

  主要设置一些参数,如canvas的长宽,canvas的context,手势锁的个数(3乘3, 4乘4),手势锁的颜色,手势滑动结束时的回调函数等。并计算出手势锁的半径。

  计算每个手势锁的圆心位置

JavaScript代码
  1. calCircleParams() {  
  2.     let n = this.cycleNum;  
  3.     let count = 0;  
  4.     for (let i = 0; i < n; i++) {  
  5.         for (let j = 0; j < n; j++){  
  6.             count++;  
  7.             let touchPoint = {  
  8.                 x: this.marge + i * (this.radius * 2 + this.margeCircle) + this.radius,  
  9.                 y: this.marge + j * (this.radius * 2 + this.margeCircle) + this.radius,  
  10.                 index: count,  
  11.                 check: "uncheck",  
  12.             }  
  13.             this.touchPoints.push(touchPoint)  
  14.         }  
  15.     }  
  16. }  

  绘制手势锁

JavaScript代码
  1. for (let i = 0; i < this.touchPoints.length; i++){  
  2.        this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)  
  3. }  
  4. this.ctx.draw(true);  

  接下来就是识别用户的滑动行为,判断用户划过了哪些圆圈,进而识别出用户的手势。

  在touchstart和touchmove事件中检测触发并更新画布

JavaScript代码
  1. onTouchStart(e) {  
  2.     // 不识别多点触控  
  3.     if (e.touches.length > 1){  
  4.         this.touchState = "unTouch";  
  5.         return;  
  6.     }  
  7.     this.touchState = "startTouch";  
  8.     this.checkTouch(e);  
  9.     let point = {x:e.touches[0].x, y:e.touches[0].y};  
  10.     this.drawCanvas(this.checkColor, point);  
  11. }  
  12.   
  13. onTouchMove(e) {  
  14.     if (e.touchState === "unTouch") {  
  15.         return;  
  16.     }  
  17.     if (e.touches.length > 1){  
  18.         this.touchState = "unTouch";  
  19.         return;  
  20.     }  
  21.     this.checkTouch(e);  
  22.     let point = {x:e.touches[0].x, y:e.touches[0].y};  
  23.     this.drawCanvas(this.checkColor, point);  
  24. }  

  检测用户是否划过某个圆圈

JavaScript代码
  1. checkTouch(e) {  
  2.     for (let i = 0; i < this.touchPoints.length; i++){  
  3.         let point = this.touchPoints[i];  
  4.         if (isPointInCycle(e.touches[0].x, e.touches[0].y, point.x, point.y, this.radius)) {  
  5.             if (point.check === 'uncheck') {  
  6.                 this.checkPoints.push(point);  
  7.                 this.lastCheckPoint = point;  
  8.             }  
  9.             point.check = "check"  
  10.             return;  
  11.         }  
  12.     }  
  13. }  

  更新画布

JavaScript代码
  1. drawCanvas(color, point) {  
  2.    //每次更新之前先清空画布  
  3.    this.ctx.clearRect(0, 0, this.width, this.height);  
  4.    //使用不同颜色和形式绘制已触发和未触发的锁  
  5.    for (let i = 0; i < this.touchPoints.length; i++){  
  6.        let point = this.touchPoints[i];  
  7.        if (point.check === "check") {  
  8.            this.drawCircle(point.x, point.y, this.radius, color);  
  9.            this.drawCircleCentre(point.x, point.y, color);  
  10.        }  
  11.        else {  
  12.            this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)  
  13.        }  
  14.    }  
  15.    //绘制已识别锁之间的线段  
  16.    if (this.checkPoints.length > 1) {  
  17.         let lastPoint = this.checkPoints[0];  
  18.         for (let i = 1; i < this.checkPoints.length; i++) {  
  19.             this.drawLine(lastPoint, this.checkPoints[i], color);  
  20.             lastPoint = this.checkPoints[i];  
  21.         }  
  22.    }  
  23.    //绘制最后一个识别锁和当前触摸点之间的线段  
  24.    if (this.lastCheckPoint && point) {  
  25.        this.drawLine(this.lastCheckPoint, point, color);  
  26.    }  
  27.    this.ctx.draw(true);  

  当用户滑动结束时调用回调函数并传递识别出的手势

JavaScript代码
  1. onTouchEnd(e) {  
  2.     typeof this.onEnd === 'function' && this.onEnd(this.checkPoints, false);  
  3. }  
  4.   
  5. onTouchCancel(e) {  
  6.     typeof this.onEnd === 'function' && this.onEnd(this.checkPoints, true);  
  7. }  

  重置和显示手势错误

JavaScript代码
  1. gestureError() {  
  2.     this.drawCanvas(this.errorColor)  
  3. }  
  4.   
  5. reset() {  
  6.     for (let i = 0; i < this.touchPoints.length; i++) {  
  7.         this.touchPoints[i].check = 'uncheck';  
  8.     }  
  9.     this.checkPoints = [];  
  10.     this.lastCheckPoint = null;  
  11.     this.drawCanvas(this.initColor);  
  12. }  

  如何调用

  在onload方法中创建lock对象并在用户触摸事件中调用相应方法

JavaScript代码
  1. onLoad: function () {  
  2.   var s = this;  
  3.   this.lock = new Lock("id-gesture-lock", wx.createCanvasContext("id-gesture-lock"), function(checkPoints, isCancel) {  
  4.     console.log('over');  
  5.     s.lock.gestureError();  
  6.     setTimeout(function() {  
  7.       s.lock.reset();  
  8.     }, 1000);  
  9.   }, {width:300, height:300})  
  10.   this.lock.drawGestureLock();  
  11.   console.log('onLoad')  
  12.   var that = this  
  13.     //调用应用实例的方法获取全局数据  
  14.   app.getUserInfo(function(userInfo){  
  15.     //更新数据  
  16.     that.setData({  
  17.       userInfo:userInfo  
  18.     })  
  19.     that.update()  
  20.   })  
  21. },  
  22. onTouchStart: function (e) {  
  23.   this.lock.onTouchStart(e);  
  24. },  
  25. onTouchMove: function (e) {  
  26.   this.lock.onTouchMove(e);  
  27. },  
  28. onTouchEnd: function (e) {  
  29.   this.lock.onTouchEnd(e);  
  30. }  

  源码地址:https://github.com/zjxfly/wx-gesture-lock/

除非特别注明,鸡啄米文章均为原创
转载请标明本文地址:http://www.jizhuomi.com/software/680.html
2017年1月6日
作者:鸡啄米 分类:软件开发 浏览: 评论:0