<!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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!