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


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中的关键字&quot;VAR&quot;使用详解 分享
Jul 31 Javascript
Function.prototype.bind用法示例
Sep 16 Javascript
Tab切换组件(选项卡功能)实例代码
Nov 21 Javascript
javascript读写json示例
Apr 11 Javascript
用console.table()调试javascript
Sep 04 Javascript
使用JQuery实现Ctrl+Enter提交表单的方法
Oct 22 Javascript
js实现纯前端的图片预览
Apr 27 Javascript
购物车前端开发(jQuery和bootstrap3)
Aug 27 Javascript
AngularJS基于provider实现全局变量的读取和赋值方法
Jun 28 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
Apr 28 Javascript
ES6 Symbol数据类型的应用实例分析
Jun 26 Javascript
vue实现数据控制视图的原理解析
Jan 07 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生成随机密码的三种方法小结
2010/09/04 PHP
php随机抽奖实例分析
2015/03/04 PHP
使用xampp搭建运行php虚拟主机的详细步骤
2015/10/21 PHP
javascript下阻止表单重复提交、防刷新、防后退
2007/08/17 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
基于socket.io和node.js搭建即时通信系统
2014/07/30 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
node.js中的socket.io的广播消息
2014/12/15 Javascript
javascript中几个容易混淆的概念总结
2015/04/14 Javascript
Angularjs制作简单的路由功能demo
2015/04/14 Javascript
javascript实现标签切换代码示例
2016/05/22 Javascript
微信小程序前端源码逻辑和工作流
2016/09/25 Javascript
jQuery 局部div刷新和全局刷新方法总结
2016/10/05 Javascript
jQuery validate插件功能与用法详解
2016/12/15 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
JavaScript实现数值自动增加动画
2017/12/28 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
2018/06/09 jQuery
对VUE中的对象添加属性
2018/09/18 Javascript
react中使用css的7中方式(最全总结)
2019/02/11 Javascript
微信小程序模板消息推送的两种实现方式
2019/08/27 Javascript
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
python使用筛选法计算小于给定数字的所有素数
2018/03/19 Python
Python中的单行、多行、中文注释方法
2018/07/19 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
使用numpngw和matplotlib生成png动画的示例代码
2021/01/24 Python
CSS3实现时间轴特效
2020/11/02 HTML / CSS
MediaMarkt比利时:欧洲最大电器连锁店
2020/12/21 全球购物
大学生个人自荐信
2014/02/24 职场文书
cf收人广告词
2014/03/14 职场文书
乡镇团委工作总结2015
2015/05/26 职场文书
第一节英语课开场白
2015/06/01 职场文书
创业计划书之蛋糕店
2019/08/29 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python
Windows和Linux上部署Golang并运行程序
2022/04/22 Servers