溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信小程序?qū)崿F(xiàn)之手勢鎖功能實(shí)例代碼

發(fā)布時間:2020-09-29 11:17:39 來源:腳本之家 閱讀:180 作者:Rattenking 欄目:web開發(fā)

設(shè)計(jì)思路流程圖

微信小程序?qū)崿F(xiàn)之手勢鎖功能實(shí)例代碼

1、全局常量

constructor(page,opts){
  // 初始化全局常量數(shù)據(jù)
  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;//坐標(biāo)點(diǎn)之間的半間距
  this.R = this.size / 2;//外圓半徑
  this.r = this.size / 4;//內(nèi)圓半徑
  // 判斷是否在緩存中存在密碼,如果存在,直接進(jìn)行第二步驟:解碼,如果不存在,進(jìn)行初始化,設(shè)置密碼
  this.pswObj = wx.getStorageSync('password') ? {
   step: 2,
   password: JSON.parse(wx.getStorageSync('password'))
  } : { step: 0 };
  // 啟動手勢鎖初始化
  this.init();
 }

2、全局變量

init(){
  const _this = this;
  // 定義全局變量,標(biāo)記start,手勢鎖的每個坐標(biāo)的中心點(diǎn)數(shù)組,記錄選中數(shù)組
  _this.flag = false;
  _this.locationArr = [];
  _this.lastPoint = [];
  _this.restPoint = [];
  // 設(shè)置canvas的寬高
  _this.page.setData({
   width : _this.width,
   height : _this.height
  });
  this.ctx = wx.createCanvasContext(this.canvasId, this);
  // 初始化中心坐標(biāo)數(shù)組
  this.location();
  // 初始化繪制圖形圓
  this.drawPo();
  // 初始化綁定事件
  this.bindEvent();
 }

3、初始化坐標(biāo)數(shù)組locationArr 和restPoint

location(){
  // 計(jì)算坐標(biāo)的x,y坐標(biāo),同時記錄當(dāng)前位置代表的數(shù)
  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),//奇數(shù)個坐標(biāo)間半間距
     y: this.size * ((i + 1) * 2 - 1),//奇數(shù)個坐標(biāo)間半間距
     count: count//每個坐標(biāo)代表的數(shù)
    });
    arr0.push({
     x: this.size * ((j + 1) * 2 - 1),//奇數(shù)個坐標(biāo)間半間距
     y: this.size * ((i + 1) * 2 - 1),//奇數(shù)個坐標(biāo)間半間距
     count: count//每個坐標(biāo)代表的數(shù)
    });
   }
  }
  this.locationArr = arr;
  this.restPoint = arr0;
 }

4、繪制手勢鎖矩陣

繪制圓函數(shù)(bool值判斷當(dāng)前繪制的是空心還是實(shí)心)

drawCle(x, y, r, bool){
  // 設(shè)置邊框顏色。
  bool ? this.ctx.setStrokeStyle(this.cleColor) : this.ctx.setFillStyle(this.cleColor);; // 注意用set
  // 設(shè)置線條的寬度。
  this.ctx.setLineWidth(2); // 注意用set
  // 開始創(chuàng)建一個路徑,需要調(diào)用fill或者stroke才會使用路徑進(jìn)行填充或描邊。
  this.ctx.beginPath();
  // 畫一條弧線。
  this.ctx.arc(x, y, r, 0, Math.PI * 2, true);
  // 關(guān)閉一個路徑
  this.ctx.closePath();
  // 畫出當(dāng)前路徑的邊框。默認(rèn)顏色色為黑色。
  bool ? this.ctx.stroke():this.ctx.fill();
  // 將之前在繪圖上下文中的描述(路徑、變形、樣式)畫到 canvas 中。
  this.ctx.draw(true);
 }

矩陣?yán)L制

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

5、觸發(fā)move時線的繪制函數(shù)

drawLine(po) {// 解鎖軌跡
  this.ctx.beginPath();
  // 線寬
  this.ctx.lineWidth = 3;
  // 起始點(diǎn)
  this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);
  // 中間轉(zhuǎn)換的點(diǎn)
  for (var i = 1; i < this.lastPoint.length; i++) {
   this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
  }
  // 正在移動選擇的點(diǎn)
  if (po) { this.ctx.lineTo(po.x, po.y);}
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.draw(true);
 }

6、獲取當(dāng)前位置的坐標(biāo)點(diǎn)函數(shù)

getPosition(e) { // 獲取touch點(diǎn)相對于canvas的坐標(biāo)
 return {
  x: e.touches[0].x,
  y: e.touches[0].y
 };
}

7、觸發(fā)touchstart事件處理

_this.page.onTouchStart = function(e){
 let po = _this.getPosition(e);//獲取當(dāng)前準(zhǔn)確坐標(biāo)
 for (let [key,val] of _this.locationArr.entries()){//循環(huán)對比最近的坐標(biāo)
  if (Math.abs(val.x - po.x) < _this.r && Math.abs(val.y - po.y) < _this.r){
   _this.flag = true;//進(jìn)入判斷,觸發(fā)touchstart事件成功
   _this.drawCle(val.x, val.y, _this.r, false);//繪制該點(diǎn)的實(shí)心內(nèi)圓
   _this.lastPoint.push(val);//記錄該點(diǎn)坐標(biāo)到lastPoint
   _this.restPoint.splice(key,1);//刪除記錄數(shù)組restPoint的該點(diǎn)坐標(biāo)
   break;//找到坐標(biāo),跳出循環(huán)
  }
 }
}

8、觸發(fā)touchmove事件處理

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

判斷是否觸發(fā)touchstart,如果觸發(fā),執(zhí)行updata函數(shù)。

更新最后點(diǎn)坐標(biāo)函數(shù)

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);
  }
  //繪制已記錄坐標(biāo)的實(shí)心圓
  for (let val of this.lastPoint) {
   this.drawCle(val.x, val.y, this.r ,false);
  }
  //繪制解鎖路線
  this.drawLine(po);
  //找到移動中的還未落點(diǎn)的精確坐標(biāo)
  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、觸發(fā)touchend事件處理

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

通過流程圖,可以更加清楚的認(rèn)識到做一個功能需要創(chuàng)建的變量和函數(shù),流程步驟更加清楚,當(dāng)然也需要制作的過程進(jìn)行優(yōu)化。建議制作一些大的功能的時候,如果流程不清楚,最好繪制流程圖,思路清晰,開發(fā)更快,考慮更周全。

總結(jié)

以上所述是小編給大家介紹的微信小程序?qū)崿F(xiàn)之手勢鎖詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對億速云網(wǎng)站的支持!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI