欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

微信小程序实现手势图案锁屏功能

程序员文章站 2022-03-21 19:35:08
本文实例为大家分享了微信小程序手势图案锁屏的具体代码,供大家参考,具体内容如下 参考 h5lock 效果图 wxml

本文实例为大家分享了微信小程序手势图案锁屏的具体代码,供大家参考,具体内容如下

参考

h5lock

效果图

微信小程序实现手势图案锁屏功能

wxml

<view class="container">
  <view class="reset" bindtap="resetpwd">重置密码</view>
  <view class="title">{{title}}</view>
  <canvas canvas-id="canvas" class="canvas" bindtouchend="ontouchend"
   bindtouchstart="ontouchstart" bindtouchmove="ontouchmove"></canvas>
</view>

js

var locker = class {
 constructor(page,opt){
  var obj = opt || {};

  this.page = page;
  this.width = obj.width || 300;
  this.height = obj.height || 300;
  this.canvasid = obj.id || 'canvas';
  this.clecolor = obj.clecolor || '#cfe6ff';
  this.clecentercolor = obj.clecentercolor || '#cfe6ff';

  var choosetype = obj.choosetype || 3;
  // 判断是否缓存有choosetype,有就用缓存,没有就用传入的值
  this.choosetype = number(wx.getstoragesync('choosetype')) || choosetype;

  this.init();
 }
 init(){
  this.pswobj = wx.getstoragesync('passwordxx') ? {
   step: 2,
   spassword: json.parse(wx.getstoragesync('passwordxx'))
  } : {};

  this.makestate();
  // 创建 canvas 绘图上下文(指定 canvasid)
  this.ctx = wx.createcanvascontext(this.canvasid,this);
  this.touchflag = false;
  this.lastpoint = [];

  // 绘制圆
  this.createcircle();
  // canvas绑定事件
  this.bindevent();
 }
 makestate() {
  if (this.pswobj.step == 2) {
   this.page.setdata({ title:'请解锁'});
  } else if (this.pswobj.step == 1) {
   // pass
  } else {
   // pass
  }
 }
 // 画圆方法
 drawcle(x,y){
  // 设置边框颜色。
  this.ctx.setstrokestyle(this.clecolor); // 注意用set
  // 设置线条的宽度。
  this.ctx.setlinewidth(2); // 注意用set
  // 开始创建一个路径,需要调用fill或者stroke才会使用路径进行填充或描边。
  this.ctx.beginpath();
  // 画一条弧线。
  this.ctx.arc(x, y, this.r, 0, math.pi * 2, true);
  // 关闭一个路径
  this.ctx.closepath();
  // 画出当前路径的边框。默认颜色色为黑色。
  this.ctx.stroke();
  // 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
  this.ctx.draw(true);
 }

 // 计算两点之间的距离的方法
 getdis(a, b) {
  return math.sqrt(math.pow(a.x - b.x, 2) + math.pow(a.y - b.y, 2));
 }

 // 创建解锁点的坐标,根据canvas的大小(默认300px)来平均分配半径
 createcircle() {
  var n = this.choosetype;
  var count = 0;
  // 计算圆半径
  this.r = this.width / (2 + 4 * n);
  this.arr = [];
  this.restpoint = [];
  var r = this.r;
  // 获取圆心坐标,以及当前圆所代表的数
  for (var i = 0; i < n; i++) {
   for (var j = 0; j < n; j++) {
    count++;
    var obj = {
     x: j * 4 * r + 3 * r,
     y: i * 4 * r + 3 * r,
     index: count
    };
    this.arr.push(obj);
    this.restpoint.push(obj);
   }
  }
  // 清空画布
  this.ctx.clearrect(0, 0, this.width, this.height);

  // 绘制所有的圆
  this.arr.foreach(current => {this.drawcle(current.x, current.y);});
 }



 // 设置密码绘制
 getposition(e) { // 获取touch点相对于canvas的坐标
  var po = {
   x: e.touches[0].x,
   y: e.touches[0].y
  };
  return po;
 }
 preciseposition(po){
  var arr = this.restpoint.filter(current => math.abs(po.x - current.x) < this.r && math.abs(po.y - current.y) < this.r);
  return arr[0];
 }
 drawpoint(obj) { // 初始化圆心

  for (var i = 0; i < this.lastpoint.length; i++) {
   this.ctx.setfillstyle(this.clecentercolor); // 注意用set方法
   this.ctx.beginpath();
   this.ctx.arc(this.lastpoint[i].x, this.lastpoint[i].y, this.r / 2, 0, math.pi * 2, true);
   this.ctx.closepath();
   this.ctx.fill();
   this.ctx.draw(true);
  }
 }
 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);
  }
  this.ctx.lineto(po.x, po.y);
  this.ctx.stroke();
  this.ctx.closepath();
  this.ctx.draw(true);
 }
 pickpoints(frompt, topt) {
  var linelength = this.getdis(frompt, topt);
  var dir = topt.index > frompt.index ? 1 : -1;

  var len = this.restpoint.length;
  var i = dir === 1 ? 0 : (len - 1);
  var limit = dir === 1 ? len : -1;

  while (i !== limit) {
   var pt = this.restpoint[i];

   if (this.getdis(pt, frompt) + this.getdis(pt, topt) === linelength) {
    this.drawpoint(pt.x, pt.y);
    this.lastpoint.push(pt);
    this.restpoint.splice(i, 1);
    if (limit > 0) {
     i--;
     limit--;
    }
   }

   i += dir;
  }
 }
 update(po) {// 核心变换方法在touchmove时候调用
  this.ctx.clearrect(0, 0, this.width, this.height);

  for (var i = 0; i < this.arr.length; i++) { // 每帧先把面板画出来
   this.drawcle(this.arr[i].x, this.arr[i].y);
  }

  this.drawpoint(this.lastpoint);// 每帧花轨迹
  this.drawline(po, this.lastpoint);// 每帧画圆心

  for (var i = 0; i < this.restpoint.length; i++) {
   var pt = this.restpoint[i];

   if (math.abs(po.x - pt.x) < this.r && math.abs(po.y - pt.y) < this.r) {
    this.drawpoint(pt.x, pt.y);
    this.pickpoints(this.lastpoint[this.lastpoint.length - 1], pt);
    break;
   }
  }
 }
 checkpass(psw1, psw2) {// 检测密码
  var p1 = '',
   p2 = '';
  for (var i = 0; i < psw1.length; i++) {
   p1 += psw1[i].index + psw1[i].index;
  }
  for (var i = 0; i < psw2.length; i++) {
   p2 += psw2[i].index + psw2[i].index;
  }
  return p1 === p2;
 }
 storepass(psw) {// touchend结束之后对密码和状态的处理
  if (this.pswobj.step == 1) {
   if (this.checkpass(this.pswobj.fpassword, psw)) {
    this.pswobj.step = 2;
    this.pswobj.spassword = psw;

    this.page.setdata({title:'密码保存成功'});

    this.drawstatuspoint('#2cff26');
    wx.setstoragesync('passwordxx', json.stringify(this.pswobj.spassword));
    wx.setstoragesync('choosetype', this.choosetype);
   } else {
    this.page.setdata({ title: '两次不一致,重新输入' });
    this.drawstatuspoint('red');
    delete this.pswobj.step;
   }
  } else if (this.pswobj.step == 2) {
   if (this.checkpass(this.pswobj.spassword, psw)) {
    this.page.setdata({ title: '解锁成功' });
    this.drawstatuspoint('#2cff26');
   } else {
    this.drawstatuspoint('red');
    this.page.setdata({ title: '解锁失败' });
   }
  } else {
   this.pswobj.step = 1;
   this.pswobj.fpassword = psw;
   this.page.setdata({ title: '再次输入' });
  }
 }
 drawstatuspoint(type) { // 初始化状态线条
  for (var i = 0; i < this.lastpoint.length; i++) {
   this.ctx.strokestyle = type;
   this.ctx.beginpath();
   this.ctx.arc(this.lastpoint[i].x, this.lastpoint[i].y, this.r, 0, math.pi * 2, true);
   this.ctx.closepath();
   this.ctx.stroke();
   this.ctx.draw(true);
  }
 }

 updatepassword() {
  wx.removestoragesync('passwordxx');
  wx.removestoragesync('choosetype');
  this.pswobj = {};
  this.page.setdata({ title: '绘制解锁图案' });
  this.reset();
 }
 reset() {
  this.makestate();
  this.createcircle();
 }
 bindevent(){
  var self = this;
  this.page.ontouchstart = function(e){
   var po = self.getposition(e);
   self.lastpoint = [];
   for (var i = 0; i < self.arr.length; i++) {
    if (math.abs(po.x - self.arr[i].x) < self.r && math.abs(po.y - self.arr[i].y) < self.r) {

     self.touchflag = true;
     self.drawpoint(self.arr[i].x, self.arr[i].y);
     self.lastpoint.push(self.arr[i]);
     self.restpoint.splice(i, 1);
     break;
    }
   }
  }

  this.page.ontouchmove = function(e){
   if (self.touchflag) {
    self.update(self.getposition(e));
   }
  }

  this.page.ontouchend = function(e){
   if (self.touchflag) {
    self.touchflag = false;
    self.storepass(self.lastpoint);
    settimeout(function () {
     self.reset();
    }, 300);
   }
  }
 }
}
module.exports = locker;

demo下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。