微信小程序之手势解锁

微信小程序版手势解锁,也是在前辈们的基础上做的改版,可以称作是仿的轮子吧

效果图:

1、首先进行页面布局,wxml文件代码:

<view class="lock-box">
    <view  class="lock-title {{titleColor}}">{{title}}</view>
    <view hidden="{{resetHidden}}" bindtap="lockreset" class="lock-reset">重置</view>
    <canvas disable-scroll="true" class="lock-cav" bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE" canvas-id="locker" style="width:686rpx;height:686rpx;"></canvas>
</view>

这里需要对解锁提示语{{title}},解锁提示语颜色{{titleColor}},重置按钮的显示隐藏{{resetHidden}}进行动态数据绑定;然后对canvas进行三个touch事件绑定;重要:一定要设置disable-scroll=”true” 属性,此属性是当手指在canvas上触摸时,当前页面(page)不会被拖拽,不然就没法正常绘图了,而且这里必须要用bindXXX,用catchXXX还是会被拖拽,而且三种事件都要加上。


2、主页js代码

// pages/main/index.js
var wxlocker = require("../../utils/wxlocker.js");
Page({
  data:{
     title:'请设置手势密码',
     resetHidden:false,
     titleColor:""
  },
  onLoad:function(options){
    // 页面初始化 options为页面跳转所带来的参数

    wxlocker.lock.init();
    this.initState();
  },
  onReady:function(){
    
  },
  onShow:function(){
    
    // 页面显示
  },
  onHide:function(){
    // 页面隐藏
  },

  onUnload:function(){
    // 页面关闭

  },
  //设置提示语与重置按钮
  initState:function(){
    var resetHidden = wxlocker.lock.resetHidden;
    var title = wxlocker.lock.title;
    var titleColor = wxlocker.lock.titleColor;
    this.setData({
      resetHidden:resetHidden,
      title:title,
      titleColor:titleColor
    });
  },
  touchS:function(e){//touchstart事件绑定
    wxlocker.lock.bindtouchstart(e);
  },
  touchM:function(e){//touchmove事件绑定
    wxlocker.lock.bindtouchmove(e);
  },
  touchE:function(e){//touchend事件绑定
    wxlocker.lock.bindtouchend(e,this.lockSucc);
    this.initState();
  },
  lockSucc:function(){//解锁成功的回调函数
    console.log("解锁成功!");
    //do something
  },
  lockreset:function(){
    wxlocker.lock.updatePassword();
    this.initState();
  }
})

3、wxlocker.js主要代码部分:

var wxlocker = function(obj){
            this.chooseType =  3; // 3*3的圆点格子
        };

创建wxlocker对象,并设置属性chooseType,代表绘制n*n的圆圈;

wxlocker.prototype.drawCle = function(x, y) { // 初始化解锁密码面板
            this.ctx.setStrokeStyle('#10AEFF');
            this.ctx.setLineWidth(1);
            this.ctx.beginPath();
            this.ctx.arc(x, y, this.r, 0, Math.PI * 2, true);
            this.ctx.closePath();
            this.ctx.stroke();
        }

给wxlocker对象添加绘制圆圈函数drawCle,传入绘制坐标(x,y);

wxlocker.prototype.drawPoint = function() { // 初始化圆心
            for (var i = 0 ; i < this.lastPoint.length ; i++) {
                this.ctx.setFillStyle('#10AEFF');
                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();
            }
        }
        wxlocker.prototype.drawStatusPoint = function(type) { // 设置手指经过的圆圈颜色,type为色值
            for (var i = 0 ; i < this.lastPoint.length ; i++) {
                this.ctx.setStrokeStyle(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();
            }
            wx.drawCanvas({
                canvasId: "locker",
                actions: this.ctx.getActions(),
                reserve:true
            });
        }
        wxlocker.prototype.drawLine = function(po, lastPoint) {// 绘制线条轨迹
            this.ctx.beginPath();
            this.ctx.setLineWidth(1);
            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();

        }

// 创建解锁点的坐标,根据canvas的大小来平均分配半径
        wxlocker.prototype.createCircle = function() {
            var  cavW = this.setCanvasSize().w;//画布宽
            var  cavH = this.setCanvasSize().h;//画布高
            var n = this.chooseType;//解锁图片的行列数
            var count = 0;//计数
            this.r = cavW / (2 + 4 * n);// 公式计算,算出半径圆圈r
            this.lastPoint = [];//手指经过圆圈的集合
            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, cavW, cavH);
            for (var i = 0 ; i < this.arr.length ; i++) {
                this.drawCle(this.arr[i].x, this.arr[i].y);
            }
            wx.drawCanvas({
                canvasId: "locker",
                actions: this.ctx.getActions(),
                reserve:false
            });
            //return arr;

        }
wxlocker.prototype.storePass = function(psw,cb) {// touchend结束之后对密码和状态的处理
            if (this.pswObj.step == 1) {//step==1表示还没有设置密码状态
                if (this.checkPass(this.pswObj.fpassword, psw)) {
                    this.pswObj.step = 2;
                    this.pswObj.spassword = psw;
                    this.resetHidden = false;
                    this.title = "密码保存成功";
                    this.titleColor = "succ";
                    this.drawStatusPoint('#09bb07');
                    wx.setStorageSync('passwordxx', JSON.stringify(this.pswObj.spassword));
                    // wx.setStorageSync('chooseType', this.chooseType);
                } else {
                    this.title = "两次绘制不一致,重新绘制";
                    this.titleColor = "error";
                    this.drawStatusPoint('#e64340');
                    delete this.pswObj.step;
                }
            } else if (this.pswObj.step == 2) {
                if (this.checkPass(this.pswObj.spassword, psw)) {
                    this.title = "解锁成功";
                    this.titleColor = "succ";
                    this.drawStatusPoint('#09bb07');
                    cb();
                } else {
                    this.title = "解锁失败";
                    this.titleColor = "error";
                    this.drawStatusPoint('#e64340');
                }
            } else {
                if(this.lastPoint.length<4){
                    this.title="密码过于简单,请至少连接4个点";
                    this.resetHidden = true;
                    this.titleColor = "error";
                    return false;
                }else{
                    this.pswObj.step = 1;
                    this.pswObj.fpassword = psw;
                    this.titleColor = "";
                    this.title = "再次输入";
                }
                
            }

        }

Ps:微信开发者工具和ios系统均测试正常,android系统暂时还有问题,有不足之处,请大家多多指点,谢谢~~

详细最新代码:https://github.com/demi520/wxapp-lock

发布者

小五

前端开发爱好者,关注前端新技术。

发表评论

邮箱地址不会被公开。