微信小程序开发教程-手势解锁实例


Posted in Javascript onJanuary 06, 2017

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

微信小程序开发教程-手势解锁实例

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

<!--index.wxml-->
<view class="container">
 <canvas canvas-id="id-gesture-lock" class="gesture-lock" bindtouchstart="onTouchStart"
  bindtouchmove="onTouchMove" bindtouchend="onTouchEnd"></canvas>
</view>
.gesture-lock {
  margin: 100rpx auto;
  width: 300px;
  height: 300px;
  background-color: #ffffff;
}

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

初始化

constructor(canvasid, context, cb, opt){
    this.touchPoints = [];
    this.checkPoints = [];
    this.canvasid = canvasid;
    this.ctx = context;
    this.width = opt && opt.width || 300; //画布长度
    this.height = opt && opt.height || 300; //画布宽度
    this.cycleNum = opt && opt.cycleNum || 3;
    this.radius = 0; //触摸点半径
    this.isParamOk = false;
    this.marge = this.margeCircle = 25; //触摸点及触摸点和画布边界间隔
    this.initColor = opt && opt.initColor || '#C5C5C3';  
    this.checkColor = opt && opt.checkColor || '#5AA9EC';
    this.errorColor = opt && opt.errorColor || '#e19984';
    this.touchState = "unTouch";
    this.checkParam();
    this.lastCheckPoint = null;
    if (this.isParamOk) {
      // 计算触摸点的半径长度
      this.radius = (this.width - this.marge * 2 - (this.margeCircle * (this.cycleNum - 1))) / (this.cycleNum * 2)
      this.radius = Math.floor(this.radius);
      // 计算每个触摸点的圆心位置
      this.calCircleParams();
    }
    this.onEnd = cb; //滑动手势结束时的回调函数
  }

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

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

calCircleParams() {
    let n = this.cycleNum;
    let count = 0;
    for (let i = 0; i < n; i++) {
      for (let j = 0; j < n; j++){
        count++;
        let touchPoint = {
          x: this.marge + i * (this.radius * 2 + this.margeCircle) + this.radius,
          y: this.marge + j * (this.radius * 2 + this.margeCircle) + this.radius,
          index: count,
          check: "uncheck",
        }
        this.touchPoints.push(touchPoint)
      }
    }
  }

绘制手势锁

for (let i = 0; i < this.touchPoints.length; i++){
      this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)
   }
   this.ctx.draw(true);

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

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

onTouchStart(e) {
    // 不识别多点触控
    if (e.touches.length > 1){
      this.touchState = "unTouch";
      return;
    }
    this.touchState = "startTouch";
    this.checkTouch(e);
    let point = {x:e.touches[0].x, y:e.touches[0].y};
    this.drawCanvas(this.checkColor, point);
  }

  onTouchMove(e) {
    if (e.touchState === "unTouch") {
      return;
    }
    if (e.touches.length > 1){
      this.touchState = "unTouch";
      return;
    }
    this.checkTouch(e);
    let point = {x:e.touches[0].x, y:e.touches[0].y};
    this.drawCanvas(this.checkColor, point);
  }

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

checkTouch(e) {
    for (let i = 0; i < this.touchPoints.length; i++){
      let point = this.touchPoints[i];
      if (isPointInCycle(e.touches[0].x, e.touches[0].y, point.x, point.y, this.radius)) {
        if (point.check === 'uncheck') {
          this.checkPoints.push(point);
          this.lastCheckPoint = point;
        }
        point.check = "check"
        return;
      }
    }
  }

更新画布

drawCanvas(color, point) {
    //每次更新之前先清空画布
    this.ctx.clearRect(0, 0, this.width, this.height);
    //使用不同颜色和形式绘制已触发和未触发的锁
    for (let i = 0; i < this.touchPoints.length; i++){
      let point = this.touchPoints[i];
      if (point.check === "check") {
        this.drawCircle(point.x, point.y, this.radius, color);
        this.drawCircleCentre(point.x, point.y, color);
      }
      else {
        this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)
      }
    }
    //绘制已识别锁之间的线段
    if (this.checkPoints.length > 1) {
       let lastPoint = this.checkPoints[0];
       for (let i = 1; i < this.checkPoints.length; i++) {
         this.drawLine(lastPoint, this.checkPoints[i], color);
         lastPoint = this.checkPoints[i];
       }
    }
    //绘制最后一个识别锁和当前触摸点之间的线段
    if (this.lastCheckPoint && point) {
      this.drawLine(this.lastCheckPoint, point, color);
    }
    this.ctx.draw(true);
  }

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

onTouchEnd(e) {
    typeof this.onEnd === 'function' && this.onEnd(this.checkPoints, false);
  }

  onTouchCancel(e) {
    typeof this.onEnd === 'function' && this.onEnd(this.checkPoints, true);
  }

重置和显示手势错误

 

gestureError() {
    this.drawCanvas(this.errorColor)
  }

  reset() {
    for (let i = 0; i < this.touchPoints.length; i++) {
      this.touchPoints[i].check = 'uncheck';
    }
    this.checkPoints = [];
    this.lastCheckPoint = null;
    this.drawCanvas(this.initColor);
  }

如何调用

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

onLoad: function () {
  var s = this;
  this.lock = new Lock("id-gesture-lock", wx.createCanvasContext("id-gesture-lock"), function(checkPoints, isCancel) {
   console.log('over');
   s.lock.gestureError();
   setTimeout(function() {
    s.lock.reset();
   }, 1000);
  }, {width:300, height:300})
  this.lock.drawGestureLock();
  console.log('onLoad')
  var that = this
  //调用应用实例的方法获取全局数据
  app.getUserInfo(function(userInfo){
   //更新数据
   that.setData({
    userInfo:userInfo
   })
   that.update()
  })
 },
 onTouchStart: function (e) {
  this.lock.onTouchStart(e);
 },
 onTouchMove: function (e) {
  this.lock.onTouchMove(e);
 },
 onTouchEnd: function (e) {
  this.lock.onTouchEnd(e);
 }

源码地址:源码下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript window对象属性整理
Oct 24 Javascript
jquery操作checkbox示例分享
Jul 21 Javascript
JavaScript中使用arguments获得函数传参个数实例
Aug 27 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
Jun 23 Javascript
更靠谱的H5横竖屏检测方法(js代码)
Sep 13 Javascript
详解AngularJS2 Http服务
Jun 26 Javascript
Vue数据双向绑定的深入探究
Nov 27 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
Jan 18 Javascript
Vue 动态组件components和v-once指令的实现
Aug 30 Javascript
node.js +mongdb实现登录功能
Jun 18 Javascript
简单了解vue 插值表达式Mustache
Jul 22 Javascript
javascript数组includes、reduce的基本使用
Jul 02 Javascript
jQuery ajax的功能实现方法详解
Jan 06 #Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
Jan 06 #Javascript
Jqprint实现页面打印
Jan 06 #Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
Jan 06 #Javascript
jQuery EasyUi 验证功能实例解析
Jan 06 #Javascript
jQuery编写网页版2048小游戏
Jan 06 #Javascript
利用JQuery实现datatables插件的增加和删除行功能
Jan 06 #Javascript
You might like
短波收音机简介
2021/03/01 无线电
PHP无限分类的类
2007/01/02 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
php通过隐藏表单控件获取到前两个页面的url
2014/09/09 PHP
php打乱数组二维数组多维数组的简单实例
2016/06/17 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
清华大学出版的事半功倍系列 javascript全部源代码
2007/05/04 Javascript
使用js如何实现全选与全不选
2013/12/30 Javascript
教你如何使用PHP输出中文JSON字符串
2014/05/22 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
2014/08/16 Javascript
封装了jQuery的Ajax请求全局配置
2015/02/05 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
详细讲解vue2+vuex+axios
2017/05/27 Javascript
vue-router路由参数刷新消失的问题解决方法
2017/06/17 Javascript
JavaScript学习笔记之惰性函数示例详解
2017/08/27 Javascript
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
基于复选框demo(分享)
2017/09/27 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
Python使用三种方法实现PCA算法
2017/12/12 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
2019/01/04 Python
利用css3 translate完美实现表头固定效果
2017/02/28 HTML / CSS
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
会议接待欢迎词
2014/01/12 职场文书
铲车司机岗位职责
2014/03/15 职场文书
《数星星的孩子》教学反思
2014/04/11 职场文书
幼儿园师德演讲稿
2014/05/06 职场文书
安全例会汇报材料
2014/08/23 职场文书
放飞梦想演讲稿200字
2014/08/26 职场文书
大学生支教感言
2015/08/01 职场文书
2015年度工程师评职称工作总结
2015/10/14 职场文书
2016党校学习心得体会范文
2016/01/07 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
图文详解nginx日志切割的实现
2022/01/18 Servers