<font size="3"> <strong> 效果展示</strong></font><br> <font size="3"><br> </font><div align="center"><img id="aimg_uTQ12" onclick="zoom(this, this.src, 0, 0, 0)" class="zoom" src="http://7jpp2v.com1.z0.glb.clouddn.com/testh5lock.gif" onmouseover="img_onmouseoverfunc(this)" onload="thumbImg(this)" alt="" border="0"></div> <br> <font size="3"> <strong>实现原理</strong></font><br> <font size="3"> 利用HTML5的canvas,将解锁的圈圈划出,利用touch事件解锁这些圈圈,直接看代码。</font><br> <div class="blockcode"> <div id="code_VFJ"><ol> <li>function createCircle() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径<br> </li> <li> <br> </li> <li> var n = chooseType;// 画出n*n的矩阵 <br> </li> <li> lastPoint = [];<br> </li> <li> arr = [];<br> </li> <li> restPoint = [];<br> </li> <li> r = ctx.canvas.width / (2 + 4 * n);// 公式计算 半径和canvas的大小有关<br> </li> <li> for (var i = 0 ; i </li> <li> for (var j = 0 ; j </li> <li> arr.push({<br> </li> <li> x: j * 4 * r + 3 * r,<br> </li> <li> y: i * 4 * r + 3 * r<br> </li> <li> });<br> </li> <li> restPoint.push({<br> </li> <li> x: j * 4 * r + 3 * r,<br> </li> <li> y: i * 4 * r + 3 * r<br> </li> <li> });<br> </li> <li> }<br> </li> <li> }<br> </li> <li> //return arr;<br> </li> <li> }</li> </ol></div> <em onclick="copycode($('code_VFJ'));">复制代码</em> </div> <br> <font size="3"> canvas里的圆圈画好之后可以进行事件绑定</font><br> <div class="blockcode"> <div id="code_igQ"><ol> <li>function bindEvent() {<br> </li> <li> can.addEventListener("touchstart", function (e) {<br> </li> <li> var po = getPosition(e);<br> </li> <li> console.log(po);<br> </li> <li> for (var i = 0 ; i </li> <li> if (Math.abs(po.x - arr[i].x) </li> <li> <br> </li> <li> touchFlag = true;<br> </li> <li> drawPoint(arr[i].x,arr[i].y);<br> </li> <li> lastPoint.push(arr[i]);<br> </li> <li> restPoint.splice(i,1);<br> </li> <li> break;<br> </li> <li> }<br> </li> <li> }<br> </li> <li> }, false);<br> </li> <li> can.addEventListener("touchmove", function (e) {<br> </li> <li> if (touchFlag) {<br> </li> <li> update(getPosition(e));<br> </li> <li> }<br> </li> <li> }, false);<br> </li> <li> can.addEventListener("touchend", function (e) {<br> </li> <li> if (touchFlag) {<br> </li> <li> touchFlag = false;<br> </li> <li> storePass(lastPoint);<br> </li> <li> setTimeout(function(){<br> </li> <li> <br> </li> <li> init();<br> </li> <li> }, 300);<br> </li> <li> }<br> </li> <li> <br> </li> <li> <br> </li> <li> }, false);<br> </li> <li> }</li> </ol></div> <em onclick="copycode($('code_igQ'));">复制代码</em> </div> <br> <font size="3"> 接着到了最关键的步骤绘制解锁路径逻辑,通过touchmove事件的不断触发,调用canvas的moveTo方法和lineTo方法来画出折现,同时判断是否达到我们所画的圈圈里面,其中lastPoint保存正确的圈圈路径,restPoint保存全部圈圈去除正确路径之后剩余的。 Update方法:</font><br> <div class="blockcode"> <div id="code_tG7"><ol> <li>function update(po) {// 核心变换方法在touchmove时候调用<br> </li> <li> ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);<br> </li> <li> <br> </li> <li> for (var i = 0 ; i </li> <li> drawCle(arr[i].x, arr[i].y);<br> </li> <li> }<br> </li> <li> <br> </li> <li> drawPoint(lastPoint);// 每帧花轨迹<br> </li> <li> drawLine(po , lastPoint);// 每帧画圆心<br> </li> <li> <br> </li> <li> for (var i = 0 ; i </li> <li> if (Math.abs(po.x - restPoint[i].x) </li> <li> drawPoint(restPoint[i].x, restPoint[i].y);<br> </li> <li> lastPoint.push(restPoint[i]);<br> </li> <li> restPoint.splice(i, 1);<br> </li> <li> break;<br> </li> <li> }<br> </li> <li> }<br> </li> <li> <br> </li> <li> }</li> </ol></div> <em onclick="copycode($('code_tG7'));">复制代码</em> </div> <br> <font size="3"> 最后就是收尾工作,把路径里面的lastPoint保存的数组变成密码存在localstorage里面,之后就用来处理解锁验证逻辑了。</font><br> <div class="blockcode"> <div id="code_pww"><ol> <li>function storePass(psw) {// touchend结束之后对密码和状态的处理<br> </li> <li> if (pswObj.step == 1) {<br> </li> <li> if (checkPass(pswObj.fpassword, psw)) {<br> </li> <li> pswObj.step = 2;<br> </li> <li> pswObj.spassword = psw;<br> </li> <li> document.getElementById('title').innerHTML = '密码保存成功';<br> </li> <li> drawStatusPoint('#2CFF26');<br> </li> <li> window.localStorage.setItem('passwordx', JSON.stringify(pswObj.spassword));<br> </li> <li> window.localStorage.setItem('chooseType', chooseType);<br> </li> <li> } else {<br> </li> <li> document.getElementById('title').innerHTML = '两次不一致,重新输入';<br> </li> <li> drawStatusPoint('red');<br> </li> <li> delete pswObj.step;<br> </li> <li> }<br> </li> <li> } else if (pswObj.step == 2) {<br> </li> <li> if (checkPass(pswObj.spassword, psw)) {<br> </li> <li> document.getElementById('title').innerHTML = '解锁成功';<br> </li> <li> drawStatusPoint('#2CFF26');<br> </li> <li> } else {<br> </li> <li> drawStatusPoint('red');<br> </li> <li> document.getElementById('title').innerHTML = '解锁失败';<br> </li> <li> }<br> </li> <li> } else {<br> </li> <li> pswObj.step = 1;<br> </li> <li> pswObj.fpassword = psw;<br> </li> <li> document.getElementById('title').innerHTML = '再次输入';<br> </li> <li> }<br> </li> <li> <br> </li> <li> }</li> </ol></div> <em onclick="copycode($('code_pww'));">复制代码</em> </div> <br> <font size="3"> <strong>解锁组件</strong></font><br> <font size="3"> 将这个HTML5解锁写成了一个组件,放在<a href="https://github.com/lvming6816077/H5lock" target="_blank">https://github.com/lvming6816077/H5lock</a></font><br> <br> <font size="3"> </font><font size="2"><font color="#808080">转载自AlloyTeam:<a href="http://www.alloyteam.com/2015/07/html5-shi-xian-ping-mu-shou-shi-jie-suo/" target="_blank">http://www.alloyteam.com/2015/07 ... u-shou-shi-jie-suo/</a></font></font><br> <br>