H5lock.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. (function(){
  2. window.H5lock = function(obj){
  3. this.chooseType = Number(PublicLib.getCookieInfo('chooseType')) || obj.chooseType;
  4. this.linwidth = obj.linwidth
  5. this.successcolor = obj.successcolor
  6. this.successbgcolor = obj.successbgcolor
  7. this.wariningcolor = obj.wariningcolor
  8. this.wariningbgcolor = obj.wariningbgcolor
  9. this.initcolor = obj.initcolor
  10. this.inr = obj.inr
  11. this.outr = obj.outr
  12. this.initr = obj.initr
  13. this.isinput = obj.isinput
  14. this.range = obj.range
  15. };
  16. H5lock.prototype.drawCle = function(x, y,) { // 初始化解锁密码面板
  17. this.drawStatusPoint(this.successcolor)
  18. this.ctx.fillStyle = this.initcolor;
  19. this.ctx.beginPath();
  20. this.ctx.arc(x, y, this.initr * window.devicePixelRatio, 0, Math.PI * 2, true);
  21. this.ctx.closePath();
  22. this.ctx.fill();
  23. }
  24. H5lock.prototype.drawPoint = function(color,colorout) { // 初始化外环
  25. for (var i = 0 ; i < this.lastPoint.length ; i++) {
  26. this.ctx.fillStyle = colorout;
  27. this.ctx.beginPath();
  28. this.ctx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.outr * window.devicePixelRatio, 0, Math.PI * 2, false);
  29. this.ctx.closePath();
  30. this.ctx.fill();
  31. this.ctx.fillStyle = color;
  32. this.ctx.beginPath();
  33. this.ctx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.inr * window.devicePixelRatio, 0, Math.PI * 2, true);
  34. this.ctx.closePath();
  35. this.ctx.fill();
  36. }
  37. }
  38. H5lock.prototype.drawStatusPoint = function(type) { // 初始化状态线条
  39. for (var i = 0 ; i < this.lastPoint.length ; i++) {
  40. this.ctx.strokeStyle = type;
  41. this.ctx.beginPath();
  42. this.ctx.closePath();
  43. // 这是内环外边框
  44. // this.ctx.arc(this.lastPoint[i].x - 10, this.lastPoint[i].y, 0, Math.PI * 2, true);
  45. // this.ctx.stroke();
  46. }
  47. }
  48. H5lock.prototype.drawLine = function(po,color) {// 解锁轨迹
  49. this.ctx.beginPath();
  50. this.ctx.lineWidth = this.linwidth * window.devicePixelRatio;
  51. this.ctx.strokeStyle = color
  52. this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);
  53. for (var i = 1 ; i < this.lastPoint.length ; i++) {
  54. this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
  55. }
  56. this.ctx.lineTo(po.x, po.y);
  57. this.ctx.stroke();
  58. this.ctx.closePath();
  59. }
  60. H5lock.prototype.createCircle = function() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径
  61. var n = this.chooseType;
  62. var count = 0;
  63. this.r = this.ctx.canvas.width / (2 + 7.5 * n);// 公式计算
  64. var r = this.r;
  65. for (var i = 0 ; i < n ; i++) {
  66. for (var j = 0 ; j < n ; j++) {
  67. count++;
  68. var obj = {
  69. x: j * 8 * r + 4 * r,
  70. y: i * 8 * r + 4 * r,
  71. index: count
  72. };
  73. this.arr.push(obj);
  74. this.restPoint.push(obj);
  75. }
  76. }
  77. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  78. for (var i = 0 ; i < this.arr.length ; i++) {
  79. this.drawCle(this.arr[i].x, this.arr[i].y);
  80. }
  81. //return arr;
  82. }
  83. H5lock.prototype.getPosition = function(e) {// 获取touch点相对于canvas的坐标
  84. var rect = e.currentTarget.getBoundingClientRect();
  85. var po = {
  86. x: (e.touches[0].clientX - rect.left) * window.devicePixelRatio,
  87. y: (e.touches[0].clientY - rect.top) * window.devicePixelRatio
  88. };
  89. return po;
  90. }
  91. H5lock.prototype.update = function(po) {// 核心变换方法在touchmove时候调用
  92. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  93. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  94. this.drawCle(this.arr[i].x, this.arr[i].y);
  95. }
  96. this.drawPoint(this.successcolor,this.successbgcolor);// 每帧画轨迹
  97. this.drawLine(po ,this.successcolor);// 每帧画圆心
  98. console.log(window.devicePixelRatio)
  99. for (var i = 0 ; i < this.restPoint.length ; i++) {
  100. if (Math.abs(po.x - this.restPoint[i].x) < this.range * window.devicePixelRatio && Math.abs(po.y - this.restPoint[i].y) < this.range * window.devicePixelRatio) {
  101. this.lastPoint.push(this.restPoint[i]);
  102. this.restPoint.splice(i, 1);
  103. break;
  104. }
  105. }
  106. }
  107. H5lock.prototype.checkPass = function(psw1, psw2) {// 检测密码
  108. var p1 = '',
  109. p2 = '';
  110. for (var i = 0 ; i < psw1.length ; i++) {
  111. p1 += psw1[i].index + psw1[i].index;
  112. }
  113. for (var i = 0 ; i < psw2.length ; i++) {
  114. p2 += psw2[i].index + psw2[i].index;
  115. }
  116. return p1 === p2;
  117. }
  118. H5lock.prototype.storePass = function(psw) {// touchend结束之后对密码和状态的处理
  119. const password = []
  120. psw.forEach(item=>{
  121. password.push(item.index)
  122. })
  123. console.log(password)
  124. if (this.pswObj.step == 1) {
  125. if (this.checkPass(this.pswObj.fpassword, psw)) {
  126. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  127. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  128. this.drawCle(this.arr[i].x, this.arr[i].y);
  129. }
  130. this.drawPoint(this.successcolor,this.successbgcolor)
  131. this.drawLine( this.lastPoint,this.successcolor);// 每帧画圆心
  132. this.pswObj.step = 2;
  133. this.pswObj.spassword = psw;
  134. document.getElementById('title').innerHTML = '密码设置成功';
  135. // 跳转至主页面
  136. if(this.isinput) {
  137. setTimeout(() => {
  138. document.getElementById('inputpassword').click()
  139. }, 500);
  140. } else {
  141. // NEXTTODO
  142. setTimeout(() => {
  143. document.getElementById('comeback').click()
  144. }, 500);
  145. }
  146. PublicLib.putCookieInfo('passwordxx', JSON.stringify(this.pswObj.spassword));
  147. PublicLib.putCookieInfo('chooseType', this.chooseType);
  148. PublicLib.putCookieInfo('step', 2);
  149. } else {
  150. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  151. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  152. this.drawCle(this.arr[i].x, this.arr[i].y);
  153. }
  154. document.getElementById('title').innerHTML = '两次不一致,重新输入';
  155. // this.drawStatusPoint('#FF574D');
  156. this.drawPoint(this.wariningcolor,this.wariningbgcolor)
  157. this.drawLine( this.lastPoint,this.wariningcolor);// 每帧画圆心
  158. delete this.pswObj.step;
  159. }
  160. } else if (this.pswObj.step == 2) {
  161. if (this.checkPass(this.pswObj.spassword, psw)) {
  162. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  163. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  164. this.drawCle(this.arr[i].x, this.arr[i].y);
  165. }
  166. this.drawPoint(this.successcolor,this.successbgcolor)
  167. this.drawLine( this.lastPoint,this.successcolor);// 每帧画圆心
  168. document.getElementById('title').innerHTML = '解锁成功';
  169. setTimeout(() => {
  170. document.getElementById('goon').click()
  171. }, 500);
  172. } else {
  173. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  174. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  175. this.drawCle(this.arr[i].x, this.arr[i].y);
  176. }
  177. this.drawPoint(this.wariningcolor,this.wariningbgcolor)
  178. this.drawLine( this.lastPoint,this.wariningcolor);// 每帧画圆心
  179. document.getElementById('title').innerHTML = '解锁失败,请重新尝试';
  180. }
  181. } else {
  182. this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
  183. for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
  184. this.drawCle(this.arr[i].x, this.arr[i].y);
  185. }
  186. if(psw.length < 4) {
  187. this.drawPoint(this.wariningcolor,this.wariningbgcolor)
  188. this.drawLine( this.lastPoint,this.wariningcolor);// 每帧画圆心
  189. document.getElementById('title').innerHTML = '密码长度不够,请重新输入';
  190. return;
  191. }
  192. this.drawPoint(this.successcolor,this.successbgcolor)
  193. this.drawLine( this.lastPoint,this.successcolor);// 每帧画圆心
  194. this.pswObj.step = 1;
  195. this.pswObj.fpassword = psw;
  196. document.getElementById('title').innerHTML = '再次输入';
  197. }
  198. }
  199. H5lock.prototype.makeState = function() {
  200. }
  201. H5lock.prototype.setChooseType = function(type){
  202. chooseType = type;
  203. init();
  204. }
  205. H5lock.prototype.updatePassword = function(){
  206. PublicLib.putCookieInfo('passwordxx','');
  207. PublicLib.putCookieInfo('chooseType','');
  208. PublicLib.putCookieInfo('step','');
  209. this.pswObj = {};
  210. document.getElementById('title').innerHTML = '为了保护您的隐私,请设置登录手势密码吧!';
  211. this.reset();
  212. }
  213. H5lock.prototype.initDom = function(){
  214. var wrap = document.createElement('div');
  215. if(PublicLib.getCookieInfo('step') === '2') {
  216. var str = '<div id="title">请输入手势密码</div>'+
  217. '<canvas id="canvas" style="display: inline-block;"></canvas>'+
  218. '<div class="bottomtext">至少连接4个点</div>'+
  219. '<div id="updatePassword"></div>';
  220. wrap.setAttribute('style','position: absolute; left:0;right:0;');
  221. wrap.setAttribute('class','gesturepassword');
  222. wrap.innerHTML = str;
  223. document.body.appendChild(wrap);
  224. } else {
  225. var str = '<div id="title">为了保护您的隐私,请设置登录手势密码吧!</div>'+
  226. '<canvas id="canvas"style="display: inline-block;"></canvas>'+
  227. '<div class="bottomtext">至少连接4个点</div>'+
  228. '<div id="updatePassword"></div>';
  229. wrap.setAttribute('style','position: absolute; left:0;right:0;');
  230. wrap.setAttribute('class','gesturepassword');
  231. wrap.innerHTML = str;
  232. document.body.appendChild(wrap);
  233. }
  234. var canvas=document.getElementById('canvas');
  235. canvas.width=canvas.clientWidth*window.devicePixelRatio;
  236. canvas.height=canvas.clientHeight*window.devicePixelRatio;
  237. }
  238. H5lock.prototype.init = function() {
  239. this.initDom();
  240. this.pswObj = PublicLib.getCookieInfo('passwordxx') ? {
  241. step: 2,
  242. spassword: JSON.parse(PublicLib.getCookieInfo('passwordxx'))
  243. } : {};
  244. this.lastPoint = [];
  245. this.makeState();
  246. this.touchFlag = false;
  247. this.canvas = document.getElementById('canvas');
  248. this.ctx = this.canvas.getContext('2d');
  249. this.lastPoint = [];
  250. this.arr = [];
  251. this.restPoint = [];
  252. this.createCircle();
  253. this.bindEvent();
  254. }
  255. H5lock.prototype.reset = function() {
  256. this.makeState();
  257. this.lastPoint = [];
  258. this.arr = [];
  259. this.restPoint = [];
  260. this.createCircle();
  261. }
  262. H5lock.prototype.bindEvent = function() {
  263. var self = this;
  264. this.canvas.addEventListener("touchstart", function (e) {
  265. e.preventDefault();// 某些android 的 touchmove不宜触发 所以增加此行代码
  266. var po = self.getPosition(e);
  267. for (var i = 0 ; i < self.arr.length ; i++) {
  268. if (Math.abs(po.x - self.arr[i].x) < self.r && Math.abs(po.y - self.arr[i].y) < self.r) {
  269. self.touchFlag = true;
  270. self.drawPoint(self.arr[i].x,self.arr[i].y);
  271. self.lastPoint.push(self.arr[i]);
  272. self.restPoint.splice(i,1);
  273. break;
  274. }
  275. }
  276. }, { passive: false });
  277. this.canvas.addEventListener("touchmove", function (e) {
  278. if (self.touchFlag) {
  279. self.update(self.getPosition(e));
  280. }
  281. }, false );
  282. this.canvas.addEventListener("touchend", function (e) {
  283. if (self.touchFlag) {
  284. self.touchFlag = false;
  285. self.storePass(self.lastPoint);
  286. setTimeout(function(){
  287. self.reset();
  288. },
  289. 700);
  290. }
  291. }, false);
  292. document.addEventListener('touchmove', function(e){
  293. e.preventDefault();
  294. },{ passive: false });
  295. document.getElementById('updatePassword').addEventListener('click', function(){
  296. self.updatePassword();
  297. });
  298. }
  299. })();