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


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 相关文章推荐
HTML TO JavaScript 转换
Jun 26 Javascript
javascript检测页面是否缩放的小例子
May 16 Javascript
Script标签与访问HTML页面详解
Jan 10 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 Javascript
使用angular帮你实现拖拽的示例
Jul 05 Javascript
Three.js入门之hello world以及如何绘制线
Sep 25 Javascript
基于Datatables跳转到指定页的简单实例
Nov 09 Javascript
vue 1.0 结合animate.css定义动画效果
Jul 11 Javascript
JS+H5 Canvas实现时钟效果
Jul 20 Javascript
零基础之Node.js搭建API服务器的详解
Mar 08 Javascript
在微信小程序中使用图表的方法示例
Apr 25 Javascript
在vue中实现给每个页面顶部设置title
Jul 29 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
php简单浏览目录内容的实现代码
2013/06/07 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
关于PHP求解三数之和问题详析
2020/11/09 PHP
一个不错的应用,用于提交获取文章内容,不推荐用
2007/03/03 Javascript
关于 byval 与 byref 的区别分析总结
2007/10/08 Javascript
基于jQuery的message插件实现右下角弹出消息框
2011/01/11 Javascript
jquery弹出框的用法示例(2)
2013/08/26 Javascript
JS实现模仿微博发布效果实例代码
2013/12/16 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
使用jQuery判断IE浏览器版本的代码
2014/06/14 Javascript
jquery中ajax使用error调试错误的方法
2015/02/08 Javascript
浅谈JSON.parse()和JSON.stringify()
2015/07/14 Javascript
微信小程序 122100版本更新问题解决方案
2016/12/22 Javascript
详谈AngularJs 控制器、数据绑定、作用域
2017/07/09 Javascript
深入探究angular2 UI组件之primeNG用法
2017/07/26 Javascript
JS中的BOM应用
2018/02/02 Javascript
vue iview实现动态路由和权限验证功能
2018/04/17 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
vue-music 使用better-scroll遇到轮播图不能自动轮播问题
2018/12/03 Javascript
js实现页面导航层级指示效果
2020/08/25 Javascript
vue3.0中setup使用(两种用法)
2020/12/02 Vue.js
Python中的深拷贝和浅拷贝详解
2015/06/03 Python
python实现文本去重且不打乱原本顺序
2016/01/26 Python
python实现自动登录后台管理系统
2018/10/18 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
Pytest框架之fixture的详细使用教程
2020/04/07 Python
python网络编程:socketserver的基本使用方法实例分析
2020/04/09 Python
Python3-异步进程回调函数(callback())介绍
2020/05/02 Python
iframe在移动端的缩放的示例代码
2018/10/12 HTML / CSS
Argos官网:英国家喻户晓的百货零售连锁商
2017/04/03 全球购物
照片礼物和装饰:MyPhoto
2019/11/02 全球购物
村捐赠仪式答谢词
2014/01/21 职场文书
师德师风承诺书
2014/05/23 职场文书
股份合作协议书
2014/09/10 职场文书
房屋租赁意向书范本
2015/05/09 职场文书
ConditionalOnProperty配置swagger不生效问题及解决
2022/06/14 Java/Android