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


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 相关文章推荐
基于jquery的代码显示区域自动拉长效果
Dec 07 Javascript
JS动态添加option和删除option(附实例代码)
Apr 01 Javascript
js网页版计算器的简单实现
Jul 02 Javascript
JavaScript实现查找字符串中第一个不重复的字符
Dec 29 Javascript
原生javascript实现解析XML文档与字符串
Mar 01 Javascript
返回函数的JavaScript函数
Jun 14 Javascript
AngularJS中下拉框的高级用法示例
Oct 11 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
Oct 16 Javascript
mui框架 页面无法滚动的解决方法(推荐)
Jan 25 Javascript
vue弹窗组件使用方法
Apr 28 Javascript
jQuery仿移动端支付宝键盘的实现代码
Aug 15 jQuery
ES6基础之字符串和函数的拓展详解
Aug 22 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学习资源和链接.
2006/12/05 PHP
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
2012/01/12 PHP
php上传文件常见问题总结
2015/02/03 PHP
Laravel中正确地返回HTTP状态码方法示例
2019/09/10 PHP
网易JS面试题与Javascript词法作用域说明
2010/11/09 Javascript
JavaScript Math.floor方法(对数值向下取整)
2015/01/09 Javascript
深入理解JavaScript系列(31):设计模式之代理模式详解
2015/03/03 Javascript
jQuery实现切换字体大小的方法
2015/03/10 Javascript
jQuery取消特定的click事件
2016/02/29 Javascript
AngularJS获取json数据的方法详解
2017/05/27 Javascript
node+express+ejs使用模版引擎做的一个示例demo
2017/09/18 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
2018/09/20 Javascript
JavaScript 2018 中即将迎来的新功能
2018/09/21 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
javascript实现画板功能
2020/04/12 Javascript
[05:05]第三天的dota2
2013/07/29 DOTA
[02:12]2019完美世界全国高校联赛(春季赛)报名开启
2019/03/01 DOTA
python内置数据类型之列表操作
2018/11/12 Python
python 划分数据集为训练集和测试集的方法
2018/12/11 Python
python语言元素知识点详解
2019/05/15 Python
Python Django 命名空间模式的实现
2019/08/09 Python
在keras中获取某一层上的feature map实例
2020/01/24 Python
基于python实现操作git过程代码解析
2020/07/27 Python
美国照明、家居装饰和家具购物网站:Bellacor
2017/09/20 全球购物
美国高端牛仔品牌:Silver Jeans
2019/12/12 全球购物
小学毕业感言50字
2014/02/16 职场文书
主持词开场白
2014/03/17 职场文书
蓝颜请假条
2014/04/11 职场文书
医院合作协议书
2014/08/19 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
资源环境与城乡规划管理专业自荐书
2014/09/26 职场文书
入党函调证明材料
2014/12/24 职场文书
2016七夕情人节感言
2015/12/09 职场文书
小学生节约用水倡议书
2019/08/12 职场文书
python通过新建环境安装tfx的问题
2022/05/20 Python