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


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 相关文章推荐
提高网站信任度的技巧
Oct 17 Javascript
javascript 隔行换色函数代码
Oct 24 Javascript
jquery.combobox中文api和例子,修复了上面的小bug
Mar 28 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
Nov 19 Javascript
Jquery弹出层插件ThickBox的使用方法
Dec 09 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
Oct 01 Javascript
很棒的Bootstrap选项卡切换效果
Jul 01 Javascript
JavaScript优化以及前段开发小技巧
Feb 02 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
Mar 03 Javascript
vue中vee validate表单校验的几种基本使用
Jun 25 Javascript
js实现div色块碰撞
Jan 16 Javascript
vue 使用class创建和清除水印的示例代码
Dec 25 Vue.js
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
「OVERLORD」动画重要删减!雅儿贝德的背叛?至尊猎杀队结成
2020/04/09 日漫
利用PHP实现与ASP Banner组件相似的类
2006/10/09 PHP
如何使用PHP往windows中添加用户
2006/12/06 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC
2020/02/16 PHP
JavaScript中的面向对象介绍
2012/06/30 Javascript
jquery二级导航内容均分的原理及实现
2013/08/13 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
jQuery使用after()方法在元素后面添加多项内容的方法
2015/03/26 Javascript
JavaScript中reduce()方法的使用详解
2015/06/09 Javascript
js生成随机数的过程解析
2015/11/24 Javascript
Sortable.js拖拽排序使用方法解析
2016/11/04 Javascript
Webpack打包慢问题的完美解决方法
2017/03/16 Javascript
vue.js中v-on:textInput无法执行事件问题的解决过程
2017/07/12 Javascript
vue.js数据绑定操作详解
2018/04/23 Javascript
详解VUE项目中安装和使用vant组件
2019/04/28 Javascript
vue+springboot+element+vue-resource实现文件上传教程
2020/10/21 Javascript
Python实现的一个简单LRU cache
2014/09/26 Python
Python随手笔记第一篇(2)之初识列表和元组
2016/01/23 Python
详解appium+python 启动一个app步骤
2017/12/20 Python
Python线性拟合实现函数与用法示例
2018/12/13 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
CSS3 简单又实用的5个属性
2010/03/04 HTML / CSS
浅谈基于Canvas的手绘风格图形库Rough.js
2018/03/19 HTML / CSS
HTML里显示pdf、word、xls、ppt的方法示例
2020/04/14 HTML / CSS
如何写一个Java类既可以用作applet也可以用作java应用
2016/01/18 面试题
大学生暑期实践感言
2014/02/26 职场文书
办公自动化专业大学生职业规划书
2014/03/06 职场文书
租房协议书
2014/09/12 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
保证金退回承诺函格式
2015/01/21 职场文书
2015年酒店年度工作总结
2015/05/23 职场文书
干货:如何写好观后感 !
2019/05/21 职场文书
如何用JavaScript实现一个数组惰性求值库
2021/05/05 Javascript
Python获取指定日期是"星期几"的6种方法
2022/03/13 Python