当前位置: 首页 > 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;其含义是“多…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...