使用canvas怎么實(shí)現(xiàn)一個(gè)手勢(shì)解鎖功能?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、網(wǎng)頁(yè)空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、寧縣網(wǎng)站維護(hù)、網(wǎng)站推廣。
手勢(shì)解鎖
通過(guò)手指將屏幕上的九個(gè)點(diǎn)依次連接起來(lái)形成一個(gè)圖案,所以叫圖案解鎖。如上圖每一個(gè)解鎖圓圈后面其實(shí)都是一個(gè)數(shù)字,每次比較的并不是是用戶畫出來(lái)的圖案,而是每次手指經(jīng)過(guò)圖案時(shí)串聯(lián)起來(lái)的圓圈下的數(shù)字組成的密碼字符串,本質(zhì)上我們比較的還是字符串的密碼,只不過(guò)站在用戶的角度看是繪制出來(lái)的圖案。圖案的記憶遠(yuǎn)比數(shù)字字符串記的牢固。
實(shí)現(xiàn)步驟
繪制密碼盤
密碼盤的繪制比較簡(jiǎn)單,唯一需要注意需要通過(guò)動(dòng)態(tài)計(jì)算使九個(gè)點(diǎn)圍成的正方式始終在屏幕的中間位置,在手機(jī)上還需要減去狀態(tài)欄的高度。
var width = $(document).width(); var height = $(document).height() - 40; //減去手機(jī)狀態(tài)欄的高度 //九宮格其實(shí)就是九個(gè)點(diǎn),9個(gè)點(diǎn)的坐標(biāo)對(duì)象 var lockCicle = { x: 0, //x坐標(biāo) y: 0, //y坐標(biāo) color: "#999999", state: "1" //狀態(tài)當(dāng)前點(diǎn)是否已經(jīng)被鏈接過(guò) }; var offset = (width - height) / 2; //計(jì)算偏移量 var arr = []; //九個(gè)點(diǎn)的坐標(biāo)數(shù)組 //計(jì)算九個(gè)點(diǎn)坐標(biāo)的方法 for (var i = 1; i <= 3; i++) { //每一行 for (var j = 1; j <= 3; j++) { //每一行的每一個(gè) var lockCicle = {}; //橫屏 if (offset > 0) { lockCicle.x = (height / 4) * j + Math.abs(offset); lockCicle.y = (height / 4) * i; lockCicle.state = 0; //豎屏 } else { lockCicle.x = (width / 4) * j; lockCicle.y = (width / 4) * i + Math.abs(offset); lockCicle.state = 0; } arr.push(lockCicle); } } //初始化界面的方法 function init() { ctx.clearRect(0, 0, width, height); //清空畫布 pointerArr = []; //清楚繪制路徑 for (var i = 0; i < arr.length; i++) { arr[i].state = 0; //清除繪制狀態(tài) drawPointer(i); } } //繪制九宮格解鎖界面 function drawPointer(i) { ctx.save(); var radius = 0; if (hastouch) { radius = width / 12; } else { radius = 24; } var _fillStyle = "#dd514c"; var _strokeStyle = "#dd514c"; //不同狀態(tài)顯示不同顏色 if (arr[i].state == 1) { _strokeStyle = "#1bd6c5"; } //繪制原點(diǎn) ctx.beginPath(); ctx.fillStyle = _fillStyle; ctx.arc(arr[i].x, arr[i].y, 6, 0, Math.PI * 2, false); ctx.fill(); ctx.closePath(); //繪制圓圈 ctx.beginPath(); ctx.strokeStyle = _strokeStyle; ctx.lineWidth = 0.3; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.arc(arr[i].x, arr[i].y, radius, 0, Math.PI * 2, false); ctx.stroke(); ctx.closePath(); ctx.restore(); } //初始化界面 init();
繪制連線
繪制連線的方法
var pointerArr = []; //連接線點(diǎn)的坐標(biāo)數(shù)組 var startX, startY; //線條起始點(diǎn) var puts = []; //經(jīng)過(guò)的九個(gè)點(diǎn)的數(shù)組 var currentPointer; //當(dāng)前點(diǎn)是否已經(jīng)連接 var pwd = []; //密碼 var confirmPwd = []; //確認(rèn)密碼 var unlockFlag = false; //是否解鎖的標(biāo)志 /** ** 繪制鏈接線的方法,將坐標(biāo)數(shù)組中的點(diǎn)繪制在canvas畫布中 **/ function drawLinePointer(x, y, flag) { ctx.clearRect(0, 0, width, height); ctx.save(); ctx.beginPath(); ctx.strokeStyle = "#1bd6c5"; ctx.lineWidth = 5; ctx.lineCap = "round"; ctx.lineJoin = "round"; for (var i = 0; i < pointerArr.length; i++) { if (i == 0) { ctx.moveTo(pointerArr[i].x, pointerArr[i].y); } else { ctx.lineTo(pointerArr[i].x, pointerArr[i].y); } } ctx.stroke(); ctx.closePath(); ctx.restore(); for (var i = 0; i < arr.length; i++) { drawPointer(i); //繪制圓圈和原點(diǎn) if (ctx.isPointInPath(x, y) && currentPointer != i) { //判斷鼠標(biāo)點(diǎn)擊是否在圓中 pointerArr.push({ x: arr[i].x, y: arr[i].y }); currentPointer = i; puts.push(i + 1); startX = arr[i].x; startY = arr[i].y; arr[i].state = 1; } } if (flag) { ctx.save(); ctx.beginPath(); ctx.globalCompositeOperation = "destination-over"; ctx.strokeStyle = "#e2e0e0"; ctx.lineWidth = 5; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.moveTo(startX, startY); ctx.lineTo(x, y); ctx.stroke(); ctx.beginPath(); ctx.restore(); } }
綁定事件
連線的過(guò)程就是將 3 個(gè) touch(移動(dòng)端) 事件組合起來(lái)獲取當(dāng)前位置的坐標(biāo)放入數(shù)組中,然后將這些坐標(biāo)渲染到界面上的過(guò)程。
touchstart (mousedown) 當(dāng)手指(鼠標(biāo))按下時(shí)設(shè)置 isMouseDown=true,同時(shí)將該點(diǎn)的坐標(biāo)保存到線條數(shù)組中,并將數(shù)組中的點(diǎn)繪制出來(lái)。
touchmove (mousemove) 當(dāng) isMouseDown=true 時(shí) 將手指(鼠標(biāo))移動(dòng)過(guò)程中所有的坐標(biāo)點(diǎn)都保存到蕭條數(shù)組中,并將數(shù)組中的點(diǎn)繪制出來(lái)。
mouseup (mouseup) 當(dāng)手指(鼠標(biāo))松開后設(shè)置 isMouseDown=fasle.將數(shù)組中的所有點(diǎn)繪制出來(lái),清空 pointerArr 數(shù)組,然后比較連接的點(diǎn)的數(shù)量如果小于 6(自己設(shè)置,一般密碼 6 位以上)給一個(gè)密碼長(zhǎng)度不夠的提示,清空 puts 數(shù)組,重新調(diào)用 init 方法初始化界面,如果大于等于 6 則密碼設(shè)置成功。
//兼容移動(dòng)觸摸的事件寫法 var hastouch = "ontouchstart" in window ? true : false, tapstart = hastouch ? "touchstart" : "mousedown", tapmove = hastouch ? "touchmove" : "mousemove", tapend = hastouch ? "touchend" : "mouseup"; //綁定按下事件 lockCnavs.addEventListener(tapstart, function(e) { isMouseDown = true; var x1 = hastouch ? e.targetTouches[0].pageX : e.clientX - canvas.offsetLeft; var y1 = hastouch ? e.targetTouches[0].pageY : e.clientY - canvas.offsetTop; drawLinePointer(x1, y1, true); }); //移動(dòng)時(shí)候,將經(jīng)過(guò)的坐標(biāo)點(diǎn)全部保存起來(lái) lockCnavs.addEventListener(tapmove, function(e) { if (isMouseDown) { var x1 = hastouch ? e.targetTouches[0].pageX : e.clientX - canvas.offsetLeft; var y1 = hastouch ? e.targetTouches[0].pageY : e.clientY - canvas.offsetTop; drawLinePointer(x1, y1, true); } }); //取消 lockCnavs.addEventListener(tapend, function(e) { drawLinePointer(0, 0, false); isMouseDown = false; pointerArr = []; if (puts.length >= 6) { alert("你的圖案密碼是: [ " + puts.join(" > ") + " ]"); if (unlockFlag) { //解鎖 unlock(); } else { //設(shè)置解鎖密碼 settingUnlockPwd(); } } else { if (puts.length >= 1) { alert("你的圖案密碼太簡(jiǎn)單了~~~"); init(); } } puts = []; });
實(shí)現(xiàn)解鎖邏輯
通過(guò)上面幾步的操作,九宮格解鎖每一次繪圖之后的數(shù)據(jù)和顯示效果都有了,現(xiàn)在只需要在關(guān)鍵地方添加相應(yīng)邏輯代碼就可以了,這里主要介紹它的實(shí)現(xiàn)邏輯就不對(duì)代碼做封裝了。
相關(guān)代碼
//設(shè)置解鎖密碼和解鎖測(cè)試 function settingUnlockPwd() { if (pwd.length <= 0) { pwd = puts; init(); $("header").text("再次繪制解鎖圖案"); } else if (confirmPwd.length <= 0) { confirmPwd = puts; } console.log(pwd + " " + confirmPwd); //筆記兩次密碼是否正確 if (pwd.length > 0 && confirmPwd.length > 0) { if (compareArr(pwd, confirmPwd)) { $("header").text("解鎖圖案繪制成功"); init(); } else { $("header").text("兩次繪制的解鎖圖案不一致"); init(); confirmPwd = []; } } } //解鎖 function unlock() { console.log("解鎖密碼:" + puts + " " + confirmPwd); if (compareArr(puts, confirmPwd)) { $("header").text("解鎖成功!頁(yè)面跳轉(zhuǎn)中......"); } else { $("header").text("解鎖圖案不正確?。?!"); init(); } } $("footer").click(function() { if ($(this).text() === "解鎖") { unlockFlag = true; init(); $("header").text("繪制解鎖圖案"); } }); //比較兩個(gè)數(shù)組(Number)是否相等 function compareArr(arr1, arr2) { return arr1.toString() === arr2.toString(); }
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。
新聞標(biāo)題:使用canvas怎么實(shí)現(xiàn)一個(gè)手勢(shì)解鎖功能
當(dāng)前鏈接:http://bm7419.com/article24/jdspje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站導(dǎo)航、自適應(yīng)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)