使用H5实现一个手势密码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>手势密码</title>
<style>
#gesture-password {
  width: 300px;
  height: 300px;
  border: 1px solid #ccc;
  position: relative;
  margin: 50px auto;
}
.dot {
  width: 40px;
  height: 40px;
  background-color: #eee;
  border-radius: 50%;
  position: absolute;
}
.dot.active {
  background-color: #3498db;
}
.line {
  position: absolute;
  width: 0;
  height: 5px;
  background-color: #3498db;
  transform-origin: 0 50%;
}
</style>
</head>
<body>

<div id="gesture-password"></div>

<script>
const container = document.getElementById('gesture-password');
const dots = [];
const password = []; // 用于存储密码
let line = null;

// 创建点
for (let i = 0; i < 9; i++) {
  const dot = document.createElement('div');
  dot.classList.add('dot');
  const x = (i % 3) * 100 + 20;
  const y = Math.floor(i / 3) * 100 + 20;
  dot.style.left = x + 'px';
  dot.style.top = y + 'px';
  container.appendChild(dot);
  dots.push(dot);
}

container.addEventListener('touchstart', (e) => {
  startDraw(e.touches[0]);
});

container.addEventListener('touchmove', (e) => {
  e.preventDefault(); // 阻止默认触摸滚动行为
  draw(e.touches[0]);
});

container.addEventListener('touchend', () => {
  endDraw();
});


function startDraw(point) {
  for (let i = 0; i < dots.length; i++) {
    if (isPointInDot(point, dots[i])) {
      dots[i].classList.add('active');
      password.push(i);
      break;
    }
  }

  line = document.createElement('div');
  line.classList.add('line');
  container.appendChild(line);

}

function draw(point) {
  if (!line) return;

  let lastDot = dots[password[password.length - 1]];
  line.style.left = lastDot.offsetLeft + lastDot.offsetWidth / 2 + 'px';
  line.style.top = lastDot.offsetTop + lastDot.offsetHeight / 2 + 'px';
  let distance = Math.sqrt(Math.pow(point.clientX - (lastDot.offsetLeft + lastDot.offsetWidth / 2), 2) + Math.pow(point.clientY - (lastDot.offsetTop + lastDot.offsetHeight / 2), 2));
  line.style.width = distance + 'px';
  let angle = Math.atan2(point.clientY - (lastDot.offsetTop + lastDot.offsetHeight / 2), point.clientX - (lastDot.offsetLeft + lastDot.offsetWidth / 2)) * 180 / Math.PI;
  line.style.transform = 'rotate(' + angle + 'deg)';

  for (let i = 0; i < dots.length; i++) {
    if (!dots[i].classList.contains('active') && isPointInDot(point, dots[i])) {
      dots[i].classList.add('active');
      password.push(i);
      line = document.createElement('div');
      line.classList.add('line');
      container.appendChild(line);
    }
  }
}

function endDraw() {
  console.log("密码:", password); // 输出当前密码
  // 在这里可以进行密码校验或其他操作

  // 重置
  password.length = 0;
  line = null;
  dots.forEach(dot => dot.classList.remove('active'));
  const lines = container.querySelectorAll('.line');
  lines.forEach(line => container.removeChild(line));
}

function isPointInDot(point
posted @   王铁柱6  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示