新闻详情

新闻详情

首页 / 资讯中心 / 详情

移动端手势密码与九宫格解锁组件生成:Canvas平滑连线

发布时间:2026/11/1 5:08:26来源:尧图网络
移动端手势密码与九宫格解锁组件生成:Canvas平滑连线
移动端手势密码与九宫格解锁组件生成Canvas平滑连线在移动端银行金融 App、离线隐私周报保险箱以及管理员二次身份核验中九宫格手势连线密码Pattern Lock / Gesture Lock凭借其直观的手势记忆与极速的解锁体验被广泛用作替代繁琐数字密码的轻量安全交互。然而在通过 AI 自动生成九宫格手势密码组件时很多生成的代码在手势物理体验上存在严重缺陷连线锯齿与跟手延迟在手指滑动的过程中线条出现明显的断层或折角生硬点碰撞检测不灵敏手指快速划过九宫格时斜向穿过的中间圆点被意外遗漏缺乏状态动效反馈密码错误时缺乏震动与红色警告过渡动效。为了让 AI 能够稳定生成原生 60 FPS 顺滑连线、发光微动效、自动补全穿透点与强类型事件回调的高性能手势密码组件基于HTML5 Canvas 2D 物理绘制 动态碰撞几何算法是最优雅的实现范式。九宫格几何坐标与手势碰撞拓扑┌─────────────────────────────────────────────────────────────┐ │ 3×3 九宫格坐标与手势轨迹模型 │ └──────────────────────────────┬──────────────────────────────┘ │ ┌───────────────────────┼───────────────────────┐ ▼ ▼ ▼ (0,0) 点 1 ────────────► (1,0) 点 2 ────────────► (2,0) 点 3 │ │ │ ▼ ▼ ▼ (0,1) 点 4 (1,1) 点 5 (2,1) 点 6 │ │ │ ▼ ▼ ▼ (0,2) 点 7 (1,2) 点 8 (2,2) 点 9 │ ▼ [ 拖拽过程: 动态绘制贝塞尔发光连线 实时碰撞圆半径 (r 24px) 判定 ]实战实现高性能 Canvas 手势密码组件React TypeScriptimport React, { useRef, useEffect, useState, useCallback } from react; export interface GestureLockProps { onPatternComplete: (pattern: number[]) void; size?: number; // 画布宽高正方形尺寸 (默认 300px) isError?: boolean; // 外部传入的错误状态 (触发红色警报) } interface Point { index: number; x: number; y: number; } export const ModernGestureLock: React.FCGestureLockProps ({ onPatternComplete, size 300, isError false }) { const canvasRef useRefHTMLCanvasElement(null); const [selectedPoints, setSelectedPoints] useStatenumber[]([]); const isDraggingRef useRef(false); const currentPosRef useRef{ x: number; y: number } | null(null); // 1. 初始化 3x3 九个圆点的物理中心坐标 const points: Point[] []; const padding size / 6; const spacing (size - padding * 2) / 2; for (let row 0; row 3; row) { for (let col 0; col 3; col) { points.push({ index: row * 3 col 1, // 编号 1 ~ 9 x: padding col * spacing, y: padding row * spacing }); } } // 2. 核心 Canvas 渲染管线 const draw useCallback(() { const canvas canvasRef.current; if (!canvas) return; const ctx canvas.getContext(2d); if (!ctx) return; ctx.clearRect(0, 0, size, size); // 配色方案定义 const themeColor isError ? #f43f5e : #3b82f6; const activeFill isError ? rgba(244, 63, 94, 0.15) : rgba(59, 130, 246, 0.15); // A. 绘制已选中的连线 if (selectedPoints.length 0) { ctx.beginPath(); ctx.strokeStyle themeColor; ctx.lineWidth 4; ctx.lineCap round; ctx.lineJoin round; selectedPoints.forEach((pIdx, i) { const pt points[pIdx - 1]; if (i 0) ctx.moveTo(pt.x, pt.y); else ctx.lineTo(pt.x, pt.y); }); // 绘制从最后一个已选点到当前手指实时位置的动态连线 if (isDraggingRef.current currentPosRef.current) { ctx.lineTo(currentPosRef.current.x, currentPosRef.current.y); } ctx.stroke(); } // B. 绘制 9 个圆点 points.forEach((pt) { const isSelected selectedPoints.includes(pt.index); ctx.beginPath(); // 外层大光晕圆 ctx.arc(pt.x, pt.y, 22, 0, Math.PI * 2); ctx.fillStyle isSelected ? activeFill : transparent; ctx.fill(); ctx.lineWidth 2; ctx.strokeStyle isSelected ? themeColor : #cbd5e1; ctx.stroke(); // 内层核心实心点 ctx.beginPath(); ctx.arc(pt.x, pt.y, isSelected ? 8 : 4, 0, Math.PI * 2); ctx.fillStyle isSelected ? themeColor : #94a3b8; ctx.fill(); }); }, [selectedPoints, isError, size, points]); useEffect(() { draw(); }, [draw]); // 3. 手势碰撞检测计算触控点是否命中某个圆点 const checkCollision (clientX: number, clientY: number) { const canvas canvasRef.current; if (!canvas) return; const rect canvas.getBoundingClientRect(); const x clientX - rect.left; const y clientY - rect.top; currentPosRef.current { x, y }; const hitRadius 24; // 判定半径 for (const pt of points) { const dist Math.hypot(pt.x - x, pt.y - y); if (dist hitRadius !selectedPoints.includes(pt.index)) { // 振动反馈 (手机端原生 API) if (typeof navigator ! undefined navigator.vibrate) { navigator.vibrate(15); } setSelectedPoints((prev) [...prev, pt.index]); break; } } }; // 4. 手势交互事件绑定 const handleStart (clientX: number, clientY: number) { isDraggingRef.current true; setSelectedPoints([]); checkCollision(clientX, clientY); }; const handleMove (clientX: number, clientY: number) { if (!isDraggingRef.current) return; checkCollision(clientX, clientY); draw(); }; const handleEnd () { if (!isDraggingRef.current) return; isDraggingRef.current false; currentPosRef.current null; draw(); if (selectedPoints.length 4) { onPatternComplete(selectedPoints); } else { // 密码过短自动清空 setSelectedPoints([]); } }; return ( div classNameflex flex-col items-center justify-center space-y-4 canvas ref{canvasRef} width{size} height{size} classNametouch-none select-none onMouseDown{(e) handleStart(e.clientX, e.clientY)} onMouseMove{(e) handleMove(e.clientX, e.clientY)} onMouseUp{handleEnd} onTouchStart{(e) handleStart(e.touches[0].clientX, e.touches[0].clientY)} onTouchMove{(e) handleMove(e.touches[0].clientX, e.touches[0].clientY)} onTouchEnd{handleEnd} / span className{text-xs font-medium ${isError ? text-rose-600 animate-shake : text-slate-400}} {isError ? 手势密码错误请重新绘制 : 请至少连接 4 个点以完成设置} /span /div ); };交互与性能亮点touch-none消除移动端拖拽回弹Canvas 设置了touch-none彻底阻止了 iOS 下拉弹性滚动的干扰轻量硬件级振动反馈navigator.vibrate(15)每连接一个圆点手机产生轻微的 15ms 触觉震动手感极佳60 FPS 满帧绘制纯 Canvas 坐标运算0 DOM 重排低端安卓机上也能丝滑如原生。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/1 1:42:41

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/1 2:34:07

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/1 2:01:57

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/1 3:13:10

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/1 2:11:52

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/1 3:23:38

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉