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


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代码
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | | 25 | | 26 | | 27 | | 28 | | 29 | | 30 | | 31 | | 32 | | 33 | | 34 | | 35 | | 36 | | 37 | | 38 | | 39 | | 40 | | 41 | | 42 | | 43 | | 44 | | 45 | | 46 | | 47 | | 48 | | 49 | | 50 | | 51 | | 52 | | 53 | | 54 | | 55 |
| | // pages/main/index.jsvar 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);
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | | 25 | | 26 | | 27 | | 28 | | 29 | | 30 | | 31 | | 32 | | 33 | | 34 | | 35 |
| | 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();
| |
| | } |
|
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | | 25 | | 26 | | 27 | | 28 | | 29 | | 30 | | 31 | | 32 | | 33 | | 34 |
| | // 创建解锁点的坐标,根据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;
| |
| | } |
|
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | | 25 | | 26 | | 27 | | 28 | | 29 | | 30 | | 31 | | 32 | | 33 | | 34 | | 35 | | 36 | | 37 | | 38 | | 39 | | 40 | | 41 | | 42 | | 43 | | 44 |
| | 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