当前位置: 首页 > news >正文

vue 手势解锁功能

效果

实现

<script setup lang="ts">
const canvasRef = ref<HTMLCanvasElement>()
const ctx = ref<CanvasRenderingContext2D | null>(null)
const width = px2px(600)
const height = px2px(700)
const radius = ref(px2px(50))const init = () => {const canvas = canvasRef.valueif (!canvas) returncanvas.width = widthcanvas.height = heightctx.value = canvas.getContext('2d')render()}
onMounted(init)// 圆
type CircleType = { x: number; y: number; n: number }
const circlePointList = ref<CircleType[]>([])
const circleChooseList = ref<CircleType[]>([])
const circleSolidWidth = px2px(5)
const drawCircle = (x: number, y: number, r = radius.value) => {// 画圆const c = ctx.valueif (!c) returnc.strokeStyle = '#CFE6FF'c.lineWidth = circleSolidWidthc.beginPath()c.arc(x, y, r, 0, 2 * Math.PI, true)c.closePath()c.stroke()
}
const renderCircleList = () => {const c = ctx.valueif (!c) returnc.clearRect(0, 0, width, height)const line_num = 3const row_num = 3const r = radius.valueconst rTotalLen = r * 2 * line_num// 算x的偏移量const paddingX = px2px(50)const w = width - paddingX * 2const marginX = (w - rTotalLen) / (line_num - 1)const offsetX = (w - marginX * (line_num - 1) - rTotalLen) / 2// 算y的偏移量const paddingY = px2px(50)const h = height - paddingY * 2const marginY = (h - r * 2 * row_num) / (row_num - 1)const offsetY = (h - marginY * (row_num - 1) - r * 2 * row_num) / 2// 循环画for (let i = 0; i < line_num; i++) {for (let j = 0; j < row_num; j++) {const x = r + j * 2 * r + marginX * j + offsetX + paddingXconst y = r + i * 2 * r + marginY * i + offsetY + paddingYdrawCircle(x, y)circlePointList.value.push({ x, y, n: circlePointList.value.length + 1 })}}
}
const drawChooseCircle = (x: number, y: number, r = radius.value, r2 = px2px(8)) => {const c = ctx.valueif (!c) returnc.strokeStyle = '#CFE6FF'c.lineWidth = circleSolidWidthc.beginPath()c.arc(x, y, r, 0, 2 * Math.PI, true)c.closePath()c.stroke()c.beginPath()c.arc(x, y, r2, 0, 2 * Math.PI, false)c.closePath()c.fillStyle = '#CFE6FF'c.fill()c.stroke()
}
const renderChooseCircle = () => {const list = circleChooseList.valuefor (let i = 0; i < list.length; i++) {const { x, y } = list[i]drawChooseCircle(x, y)}
}
const getIsChooseCircleByPoint = (x: number, y: number): { active: boolean; circle: CircleType | null } => {const list = circlePointList.valuefor (let i = 0; i < list.length; i++) {const { x: x1, y: y1 } = list[i]const r = radius.valueconst leftIs = x > x1 - r - circleSolidWidthconst rightIs = x < x1 + r + circleSolidWidthconst topIs = y > y1 - r - circleSolidWidthconst bottomIs = y < y1 + r + circleSolidWidthif (leftIs && rightIs && topIs && bottomIs) return { active: true, circle: list[i] }}return { active: false, circle: null }
}
const addCircleChoose = (c: CircleType) => {const list = circleChooseList.valueconst o = list.find((item) => item.n === c.n)if (o) returnlist.push(c)
}// 线
const drawLine = (x1: number, y1: number, x2: number, y2: number) => {const c = ctx.valueif (!c) returnc.beginPath()c.strokeStyle = '#CFE6FF'c.lineWidth = px2px(3)c.lineCap = 'round'c.moveTo(x1, y1)c.lineTo(x2, y2)c.stroke()c.closePath()
}
const renderChooseLine = () => {const list = circleChooseList.valueif (list.length < 2) returnfor (let i = 1; i < list.length; i++) {drawLine(list[i - 1].x, list[i - 1].y, list[i].x, list[i].y)}
}// 渲染
const render = () => {renderCircleList()renderChooseCircle()renderChooseLine()
}
const reset = () => {renderCircleList()circleChooseList.value = []pointList.value = []
}// 事件
const pointList = ref<{ x: number; y: number }[]>([])
const getPoint = (touch: Touch) => {const canvas = canvasRef.value// 这种方式tranform时,获取的坐标是错误的// const offsetLeft = canvas?.offsetLeft || 0// const offsetTop = canvas?.offsetTop || 0if(!canvas) return { x: 0, y: 0 }const rect = canvas.getBoundingClientRect()const offsetLeft = rect.xconst offsetTop = rect.yreturn { x: touch.clientX - offsetLeft, y: touch.clientY - offsetTop }
}
const touchstart = (e: TouchEvent) => {const touch = e.touches[0]const p = getPoint(touch)pointList.value.push(p)const o = getIsChooseCircleByPoint(p.x, p.y)if (o.active && o.circle) addCircleChoose(o.circle)
}
const touchmove = (e: TouchEvent) => {const touch = e.touches[0]const p = getPoint(touch)pointList.value.push(p)const o = getIsChooseCircleByPoint(p.x, p.y)if (o.active && o.circle) addCircleChoose(o.circle)render()const p0 = circleChooseList.value[circleChooseList.value.length - 1]if (!p0) returndrawLine(p0.x, p0.y, p.x, p.y)
}
const touchend = () => {reset()
}
</script><template><div class="flex flex-center flex-column"><BaseHead title="test"></BaseHead><h1>vue手势解锁功能</h1><canvas class="canvas" ref="canvasRef" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas></div>
</template><style lang="scss" scoped>
.page{width: 100vw;height: 100vh;box-sizing: border-box;overflow: hidden;
}
.canvas {position: fixed;top: 400px;left: 50%;transform: translateX(-50%);background-color: #ccc;
}
</style>

相关文章:

vue 手势解锁功能

效果 实现 <script setup lang"ts"> const canvasRef ref<HTMLCanvasElement>() const ctx ref<CanvasRenderingContext2D | null>(null) const width px2px(600) const height px2px(700) const radius ref(px2px(50))const init () > …...

介绍 CI / CD

目录 一、介绍 CI / CD 1、为什么要 CI / CD 方法简介 1、持续集成 2、持续交付 3、持续部署 2、GitLab CI / CD简介 3、GitLab CI / CD 的工作原理 4、基本CI / CD工作流程 5、首次设置 GitLab CI / CD 6、GitLab CI / CD功能集 一、介绍 CI / CD 在本文档中&#x…...

Stable Diffusion 3 Early Preview发布

2月22日&#xff0c;Stability AI 发布了 Stable Diffusion 3 early preview&#xff0c;这是一种开放权重的下一代图像合成模型。据报道&#xff0c;它继承了其前身&#xff0c;生成了详细的多主题图像&#xff0c;并提高了文本生成的质量和准确性。这一简短的公告并未附带公开…...

【解决(几乎)任何机器学习问题】:特征选择

当你创建了成千上万个特征后&#xff0c;就该从中挑选出⼏个了。但是&#xff0c;我们绝不应该创建成百上千个⽆⽤的特征。特征过多会带来⼀个众所周知的问题&#xff0c;即 "维度诅咒"。如果你有很多特征&#xff0c;你也必须有很多训练样本来捕捉所有特征。什么是 …...

24 双非计算机秋招总结

引言 我整理了一份 10w 字数的前端技术文档&#xff08;飞书&#xff09;&#xff0c;地址&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink&#xff0c;欢迎对前端感兴趣的同学查看、共建、分享。 PS&#xff1a;我是一名大四…...

用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增

用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增 数据源平台:用友NC65 用友NC是为集团与行业企业提供的全线管理软件产品&#xff0c;由亚太本土最大的企业管理软件提供商用友公司研发提供&#xff0c;用友NC率先采用J2EE架构和先进开放的集团级开发平台UAP&#xff0…...

【初中生讲机器学习】12. 似然函数和极大似然估计:原理、应用与代码实现

创建时间&#xff1a;2024-02-23 最后编辑时间&#xff1a;2024-02-24 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…...

【达梦数据库】查看pesg回滚段信息的视图和SQL

一些达梦回滚段是使用情况的查询SQL&#xff0c;供排查“回滚记录版本太旧&#xff0c;无法获取用户记录” 等类似问题时使用 视图名说明主库备库v$pseg_items显示回滚系统中当前回滚项信息&#xff08;回滚线程的工作信息&#xff09;总行数WORKER_THREADS1查询 no rowsv$pseg…...

UML---活动图

活动图概述 活动图&#xff08;Activity Diagram&#xff09;是UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&#xff09;中的一种行为建模工具&#xff0c;主要用于描述系统或业务流程中的一系列活动或操作。活动图通常用于描述用例中的行为&#xff0c…...

编程笔记 Golang基础 018 常量与变量

编程笔记 Golang基础 018 常量与变量 一、常量常量的定义iota特性 二、变量变量定义变量作用域零值与初始化类型转换注意事项 三、重要性 常量&#xff0c;就是在程序编译阶段就确定下来的值&#xff0c;而程序在运行时则无法改变该值。变量是程序的基本组成单位&#xff0c;用…...

如何使用Douglas-042为威胁搜索和事件应急响应提速

关于Douglas-042 Douglas-042是一款功能强大的PowerShell脚本&#xff0c;该脚本可以提升数据分类的速度&#xff0c;并辅助广大研究人员迅速从取证数据中筛选和提取出关键数据。 该工具能够搜索和识别Windows生态系统中潜在的安全漏洞&#xff0c;Douglas-042会将注意力放在…...

华为配置WLAN AC和AP之间VPN穿越示例

配置WLAN AC和AP之间VPN穿越示例 组网图形 图1 配置WLAN AC和AP之间VPN穿越示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 企业用户接入WLAN网络&#xff0c;以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff0c;不影响…...

跨语言的序列化与反序列化

在Java中实现跨语言的序列化与反序列化通常可以采用以下几种方式 使用标准的跨语言序列化格式 可以选择使用一些标准的跨语言序列化格式,例如JSON、XML、Protocol Buffers(ProtoBuf)等。这些格式都是跨语言的,可以方便地在不同的编程语言之间进行数据交换。在Java中,可以…...

软考-中级-系统集成2023年综合知识(三)

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 软考中级专栏回顾 专栏…...

五、使用脚手架

五、使用脚手架 5.1 简单的实现 创建一个 School 组件 <template> <div><h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{address}}</h2> </div> </template><script> export default {name: "S…...

抛弃chatgpt,使用微软的Cursor提升coding效率

Whats Cursor? Cursor编辑器是一个基于GPT-4的代码编辑器&#xff0c;它可以根据用户的自然语言指令或者正在编辑的代码上下文为用户提供代码建议&#xff0c;支持多种编程语言&#xff0c;如Python、Java、C/C#、go等。Cursor编辑器还可以帮助用户重构、理解和优化代码&…...

uniapp插件uViewplus的使用(涉及TS下的问题)

在技术选型后最后定了使用有团队维护的uview-plus3.0,官方文档 配置参考&#xff1a;https://juejin.cn/post/7169875753100640270 ts配置参考&#xff1a;https://blog.csdn.net/m0_70027114/article/details/132957426 引入 在项目文件的pages.json中的"easycom"…...

google浏览器chrome无法访问localhost等本地虚拟域名的解决方法

场景一&#xff1a; 谷歌浏览器访问出现&#xff1a;forbbiden 403 问题&#xff0c;或者直接跳转到正式域名(非本地虚拟域名) 访问本地的虚拟域名http://www.hd.com/phpinfo.php?p1发生了302 条状 火狐浏览器正常访问; 解决方法&#xff1a; 方法1&#xff1a;在谷歌浏览器…...

(2.2w字)前端单元测试之Jest详解篇

Jest Jest 概述 Jest是一个领先的JavaScript测试框架&#xff0c;特别适用于React和Node.js环境。由Facebook开发&#xff0c;它以简单的配置、高效的性能和易用性而闻名。Jest支持多种类型的测试&#xff0c;包括单元测试、集成测试和快照测试&#xff0c;后者用于捕获组件或…...

【C++私房菜】面向对象中的多态

文章目录 一、多态二、对象的静态类型和动态类型三、虚函数和纯虚函数1、虚函数2、虚析构函数3、抽象基类和纯虚函数4、多态的原理 四、重载、覆盖(重写)、隐藏(重定义)的对比 一、多态 OOP的核心思想是多态性(polymorphism)。多态性这个词源自希腊语&#xff0c;其含义是“多…...

ssm+java2026年毕设私人医生预约系统【源码+论文】

本系统&#xff08;程序源码&#xff09;带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于在线医疗问诊服务的研究&#xff0c;现有研究主要以综合性互联网医疗平台的宏观发展分析为主&#xff0c;专门针对基于SSM…...

在Windows和RV1126上部署ONNX肺部分割模型:一份OpenCV DNN与RKNN的完整对比实践

跨平台肺部分割模型部署实战&#xff1a;OpenCV DNN与RKNN技术选型指南 当医疗影像分析遇上边缘计算&#xff0c;开发者们常常面临一个关键抉择&#xff1a;如何在保证精度的前提下&#xff0c;将训练好的深度学习模型高效部署到不同计算平台&#xff1f;本文将以肺部分割模型为…...

【STM32F4系列】【HAL库】【实战解析】MPU6050 DMP姿态解算与I2C通信优化

1. MPU6050与DMP库基础解析 第一次接触MPU6050时&#xff0c;我被它小巧的体积和强大的功能震撼到了。这个售价不到10元的芯片&#xff0c;居然能同时测量三轴角加速度和三轴线加速度。在实际项目中&#xff0c;我发现直接读取原始数据并不难&#xff0c;但要想获得稳定的姿态信…...

【STM32实战】步进电机S型曲线算法优化与误差补偿策略

1. 为什么需要S型曲线算法 我第一次用步进电机做项目时&#xff0c;直接给电机发固定频率的脉冲让它转起来。结果电机启动瞬间发出"咔咔"的异响&#xff0c;运行起来也一顿一顿的。后来才知道&#xff0c;步进电机最怕的就是突然加速或急停&#xff0c;这会导致丢步、…...

遥感智能体模块全景解析:从任务拆解到工作流编排

1. 遥感智能体的核心架构设计 第一次接触遥感智能体&#xff08;RS-Agent&#xff09;这个概念时&#xff0c;很多人会感到困惑&#xff1a;它和传统遥感处理软件有什么区别&#xff1f;简单来说&#xff0c;RS-Agent更像是一个"会思考的助手"。我参与过几个遥感智能…...

vLLM生产-解码分离架构:从概念到部署的吞吐优化实践

1. 为什么需要生产-解码分离架构 第一次部署大模型在线服务时&#xff0c;我盯着监控面板上的GPU利用率曲线直挠头——为什么计算单元总是间歇性满载又突然空闲&#xff1f;后来发现这是典型的Prefill-Decode耦合架构的弊端。就像餐厅里同一个厨师既要负责备菜&#xff08;切配…...

不用命令行!Win11任务栏图标消失的图形化解决方案(Explorer重启神器推荐)

Win11任务栏图标消失&#xff1f;5种可视化修复方案与深度解析 每次切换虚拟桌面后&#xff0c;Win11任务栏图标集体"失踪"的毛病&#xff0c;堪称微软系统最顽固的"幽灵故障"之一。作为从Windows 95时代就存在的资源管理器痼疾&#xff0c;这个问题在Win1…...

OpenClaw自动化测试:Qwen3.5-9B在API接口校验中的实战应用

OpenClaw自动化测试&#xff1a;Qwen3.5-9B在API接口校验中的实战应用 1. 为什么选择OpenClaw做接口自动化测试 去年接手一个个人项目时&#xff0c;我遇到了接口测试的痛点&#xff1a;每次后端更新都要手动验证几十个API&#xff0c;不仅耗时还容易遗漏边缘case。尝试过Pos…...

别再花钱买云API了!手把手教你用Docker+Ollama在本地免费跑通Strix渗透测试

零成本打造企业级渗透测试环境&#xff1a;DockerOllama本地化实战指南 当安全团队每月收到云服务商五位数的API账单时&#xff0c;当关键测试任务因网络抖动被迫中断时&#xff0c;越来越多的技术决策者开始重新审视渗透测试的基础架构。本文将揭示如何用消费级硬件构建媲美商…...

公开信息整理|2026年3月27日:楼市需求、长护险覆盖、个体工商户增长与部分国际动态速览

&#x1f525;个人主页&#xff1a;杨利杰YJlio❄️个人专栏&#xff1a;《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》 《Python》 《Kali Linux》 《那些年未解决的Windows疑难杂症》&#x1f31f; 让复杂的事情更…...