微信小程序实现之手势锁功能实例代码


Posted in Javascript onJuly 19, 2018

设计思路流程图

微信小程序实现之手势锁功能实例代码

1、全局常量

constructor(page,opts){
  // 初始化全局常量数据
  this.page = page;
  this.width = opts.width || 300;
  this.height = opts.height || 300;
  this.canvasId = opts.canvasId || 'lock';
  this.type = opts.type || 3;
  this.cleColor = opts.cleColor || 'rgba(0,136,204,1)';
  this.size = this.width / this.type / 2;//坐标点之间的半间距
  this.R = this.size / 2;//外圆半径
  this.r = this.size / 4;//?仍舶刖
  // 判断是否在缓存中存在密码,如果存在,直接进行第二步骤:解码,如果不存在,进行初始化,设置密码
  this.pswObj = wx.getStorageSync('password') ? {
   step: 2,
   password: JSON.parse(wx.getStorageSync('password'))
  } : { step: 0 };
  // 启动手势锁初始化
  this.init();
 }

2、全局变量

init(){
  const _this = this;
  // 定义全局变量,标记start,手势锁的每个坐标的中心点数组,记录选中数组
  _this.flag = false;
  _this.locationArr = [];
  _this.lastPoint = [];
  _this.restPoint = [];
  // 设置canvas的宽高
  _this.page.setData({
   width : _this.width,
   height : _this.height
  });
  this.ctx = wx.createCanvasContext(this.canvasId, this);
  // 初始化中心坐标数组
  this.location();
  // 初始化绘制图形圆
  this.drawPo();
  // 初始化绑定事件
  this.bindEvent();
 }

3、初始化坐标数组locationArr 和restPoint

location(){
  // 计算坐标的x,y坐标,同时记录当前位置代表的数
  let count = 0,arr = [],arr0 = [];
  for(let i = 0; i < this.type; i++){
   for(let j = 0 ; j < this.type; j++){
    count++;
    arr.push({
     x: this.size * ((j + 1) * 2 - 1),//奇数个坐标间半间距
     y: this.size * ((i + 1) * 2 - 1),//奇数个坐标间半间距
     count: count//每个坐标代表的数
    });
    arr0.push({
     x: this.size * ((j + 1) * 2 - 1),//奇数个坐标间半间距
     y: this.size * ((i + 1) * 2 - 1),//奇数个坐标间半间距
     count: count//每个坐标代表的数
    });
   }
  }
  this.locationArr = arr;
  this.restPoint = arr0;
 }

4、绘制手势锁矩阵

绘制圆函数(bool值判断当前绘制的是空心还是实心)

drawCle(x, y, r, bool){
  // 设置边框颜色。
  bool ? this.ctx.setStrokeStyle(this.cleColor) : this.ctx.setFillStyle(this.cleColor);; // 注意用set
  // 设置线条的宽度。
  this.ctx.setLineWidth(2); // 注意用set
  // 开始创建一个路径,需要调用fill或者stroke才会使用路径进行填充或描边。
  this.ctx.beginPath();
  // 画一条弧线。
  this.ctx.arc(x, y, r, 0, Math.PI * 2, true);
  // 关闭一个路径
  this.ctx.closePath();
  // 画出当前路径的边框。默认颜色色为黑色。
  bool ? this.ctx.stroke():this.ctx.fill();
  // 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
  this.ctx.draw(true);
 }

矩阵绘制

drawPo(){
  // 绘制空心圆,绘制之前,清空canvas,防止重复绘制
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.locationArr.forEach(current => {
   this.drawCle(current.x, current.y, this.R, true);
  });
 }

5、触发move时线的绘制函数

drawLine(po) {// 解锁轨迹
  this.ctx.beginPath();
  // 线宽
  this.ctx.lineWidth = 3;
  // 起始点
  this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);
  // 中间转换的点
  for (var i = 1; i < this.lastPoint.length; i++) {
   this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
  }
  // 正在移动选择的点
  if (po) { this.ctx.lineTo(po.x, po.y);}
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.draw(true);
 }

6、获取当前位置的坐标点函数

getPosition(e) { // 获取touch点相对于canvas的坐标
 return {
  x: e.touches[0].x,
  y: e.touches[0].y
 };
}

7、触发touchstart事件处理

_this.page.onTouchStart = function(e){
 let po = _this.getPosition(e);//获取当前准确坐标
 for (let [key,val] of _this.locationArr.entries()){//循环对比最近的坐标
  if (Math.abs(val.x - po.x) < _this.r && Math.abs(val.y - po.y) < _this.r){
   _this.flag = true;//进入判断,触发touchstart事件成功
   _this.drawCle(val.x, val.y, _this.r, false);//绘制该点的实心内圆
   _this.lastPoint.push(val);//记录该点坐标到lastPoint
   _this.restPoint.splice(key,1);//删除记录数组restPoint的该点坐标
   break;//找到坐标,跳出循环
  }
 }
}

8、触发touchmove事件处理

_this.page.onTouchMove = function (e) {
 _this.flag && _this.updata(_this.getPosition(e));
}

判断是否触发touchstart,如果触发,执行updata函数。

更新最后点坐标函数

updata(po){
  //清空canvas
  this.ctx.clearRect(0, 0, this.width, this.height);
  //重新绘制矩阵
  for (let val of this.locationArr) {
   this.drawCle(val.x, val.y, this.R, true);
  }
  //绘制已记录坐标的实心圆
  for (let val of this.lastPoint) {
   this.drawCle(val.x, val.y, this.r ,false);
  }
  //绘制解锁路线
  this.drawLine(po);
  //找到移动中的还未落点的精确坐标
  for (let [key, val] of this.restPoint.entries()) {
   if (Math.abs(po.x - val.x) < this.r && Math.abs(po.y - val.y) < this.r) {
    this.drawCle(val.x, val.y, this.r, false);
    this.lastPoint.push(val);
    this.restPoint.splice(key, 1);
    break;
   }
  }
 }

9、触发touchend事件处理

_this.page.onTouchEnd = function (e) {
 if(_this.flag){
  _this.flag = false;
  _this.endData();
  _this.checkPassword(_this.lastPoint);
  setTimeout(function () {
   _this.reset();
  }, 500);
 }
}

通过流程图,可以更加清楚的认识到做一个功能需要创建的变量和函数,流程步骤更加清楚,当然也需要制作的过程进行优化。建议制作一些大的功能的时候,如果流程不清楚,最好绘制流程图,思路清晰,开发更快,考虑更周全。

总结

以上所述是小编给大家介绍的微信小程序实现之手势锁详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
文本加密解密
Jun 23 Javascript
做网页的一些技巧(续)
Feb 01 Javascript
Mozilla 表达式 __noSuchMethod__
Apr 05 Javascript
为指定的元素添加遮罩层的示例代码
Jan 15 Javascript
js实现遮罩层划出效果是生成div而不是显示
Jul 29 Javascript
Enter回车切换输入焦点实现思路与代码兼容各大浏览器
Sep 01 Javascript
JavaScript自学笔记(必看篇)
Jun 23 Javascript
在Vue项目中使用d3.js的实例代码
May 01 Javascript
详解JavaScript作用域和作用域链
Mar 19 Javascript
微信小程序文章详情页跳转案例详解
Jul 09 Javascript
利用JavaScript为句子加标题的3种方法示例
Jan 05 Javascript
JS实现百度搜索框
Feb 25 Javascript
React组件重构之嵌套+继承及高阶组件详解
Jul 19 #Javascript
微信小程序实现折叠展开效果
Jul 19 #Javascript
详解Angularjs 自定义指令中的数据绑定
Jul 19 #Javascript
微信小程序实现天气预报功能
Jul 18 #Javascript
vue代理和跨域问题的解决
Jul 18 #Javascript
小程序自定义组件实现城市选择功能
Jul 18 #Javascript
微信小程序实践之动态控制组件的显示/隐藏功能
Jul 18 #Javascript
You might like
记录mysql性能查询过程的使用方法
2013/05/02 PHP
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
php中使用gd库实现远程图片下载实例
2015/05/12 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
2016/10/18 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
PHP PDOStatement::getAttribute讲解
2019/02/01 PHP
jQuery '行 4954 错误: 不支持该属性或方法' 的问题解决方法
2011/01/19 Javascript
JS去除右边逗号的简单方法
2013/07/03 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
2013/10/14 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
最细致的vue.js基础语法 值得收藏!
2016/11/03 Javascript
理解javascript中的闭包
2017/01/11 Javascript
js实现图片上传预览原理分析
2017/07/13 Javascript
详解node.js中的npm和webpack配置方法
2018/01/21 Javascript
聊聊JS动画库 Velocity.js的使用
2018/03/13 Javascript
如何为vuex实现带参数的 getter和state.commit
2019/01/04 Javascript
JS用最简单的方法实现四舍五入
2019/08/27 Javascript
使用layui 的layedit定义自己的toolbar方法
2019/09/18 Javascript
javascript局部自定义鼠标右键菜单
2020/12/08 Javascript
[11:27]《一刀刀一天》之DOTA全时刻20:TI4总奖金突破920W TS赛事分析
2014/06/18 DOTA
对Python的交互模式和直接运行.py文件的区别详解
2019/06/29 Python
python切片(获取一个子列表(数组))详解
2019/08/09 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
Python 实现一行输入多个数字(用空格隔开)
2020/04/29 Python
css3设置box-pack和box-align让div里面的元素垂直居中
2014/09/01 HTML / CSS
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
英国最红的高街时尚品牌:Topshop
2016/08/05 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
资金主管岗位职责范本
2014/03/04 职场文书
美容院营销方案
2014/03/05 职场文书
拾金不昧锦旗标语
2014/06/27 职场文书
2015年出纳年终工作总结
2015/05/14 职场文书
windows11选中自动复制怎么开启? Win11自动复制所选内容的方法
2022/07/23 数码科技
python高温预警数据获取实例
2022/07/23 Python