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

uni-app在image上绘制点位并回显

在 Uni-app 中绘制多边形可以通过使用 Canvas API 来实现。Uni-app 是一个使用 Vue.js 开发所有前端应用的框架,同时支持编译为 H5、小程序等多个平台。由于 Canvas 是 H5 和小程序中都支持的 API,所以通过 Canvas 绘制多边形是一个比较通用的方法。

1. 创建一个新的 Uni-app 项目(如果还没有的话)

vue create -p dcloudio/uni-preset-vue my-uni-app
cd my-uni-app

2. 开始绘制

背景:在image上绘制多边形,并将点位回传。回传后的数据格式'(1,2),(3,4)',所以需要一些方法进行处理。如你没有转换需求,可自行删除。

<template><view class="layout-wrap"><view class="draw-wrap"><view class="camera-wrap"><img:style="{ width: `${canvasWidth}px`, height: `${canvasHeight}px` }":src="cameraUrl"mode="aspectFill"class="popup-img"/><canvasid="myCanvas"canvas-id="myCanvas"@touchstart="onTouchStart"@touchend="onTouchEnd":style="{ width: `${canvasWidth}px`, height: `${canvasHeight}px` }"></canvas></view></view><view class="btn-wrap"><view class="btn reset-btn" @click="handleClear">清 除</view><view class="btn" @click="handleSubmit">确 定</view></view></view>
</template><script>
import { addCameraRegion, getCameraId } from "@/api/cabinet";
import config from "@/config";
const baseUrl = config.baseUrl;
export default {name: "draw",data() {return {points: [], // 存储触摸点canvasWidth: "",canvasHeight: "",ctx: "",cameraUrl: "",rate: "",touchNum: 0,};},onShow() {this.init();},methods: {init() {// 获取配置及绘制图形getCameraId(config.hostInfoId).then((res) => {const data = res.data;this.monitorPoints = data.monitorPoints;this.rate =  data.monitorWidth / data.monitorHeight;this.canvasWidth = 1000this.canvasHeight = this.canvasWidth / this.rate;this.cameraUrl =baseUrl +"/api/monitor/player?cameraId=" +data.monitorCameraId +"&time=" +new Date().getTime();const ctx = uni.createCanvasContext("myCanvas");this.ctx = ctx;this.touchNum = 0this.setRect();});},onTouchStart(e) {if (this.touchNum === 0) {this.handleClear()}this.touchNum++;const touch = e.touches[0];this.points.push({ x: touch.x, y: touch.y });},onTouchEnd(e) {this.drawPolygon();this.ctx.draw();},drawPolygon() {const ctx = this.ctx;ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); // 清除画布ctx.setStrokeStyle("#00ff00"); // 设置多边形边框颜色// 设置填充样式和透明度ctx.setLineWidth(10); // 设置多边形边框宽度ctx.beginPath();this.points.forEach((point, index) => {if (index === 0) {ctx.moveTo(point.x, point.y);} else {ctx.lineTo(point.x, point.y);}});// 如果需要闭合多边形,取消注释以下行ctx.closePath();ctx.stroke();// 绘制填充ctx.setFillStyle("rgba(0, 255, 0, 0.4)");ctx.fill();},// 根据之前的数据回显多边形(如果有的话)setRect() {try {const pointsArr = this.monitorPoints.slice(1, -1).split("),(");if (pointsArr && pointsArr.length > 1) {pointsArr.map((p) => {this.points.push({x: Math.round(p.split(",")[0] / this.rate),y: Math.round(p.split(",")[1] / this.rate),});});console.log(this.canvasWidth, this.canvasHeight);console.log(this.points);this.drawPolygon();setTimeout(() => {//必须延迟执行 不然H5不显示this.ctx.draw(); //必须加上  uniapp 没这儿玩意儿 显示不出来不比原生  不加可以显示}, 200);}} catch (error) {console.error("绘制多边形时出错:", error);}},// 提交    handleSubmit() {if (this.points.length > 1) {// 转换并发送多边形的顶点坐标const scaledPoints = [];this.points.map((point) => {scaledPoints.push(`(${Math.round(point.x * this.rate)},${Math.round(point.y * this.rate)})`);});// 提交请求} else {uni.showToast({title: "请绘制",icon: "none",});}},// 清除handleClear() {this.points = [];this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); // 清除画布this.ctx.draw();},},
};
</script>
<style lang="scss" scoped>
.draw-wrap {position: relative;margin-top: 2vh;left: 7vw;
}
.camera-wrap {height: 76vh;
}
.popup-img {position: absolute;top: 0;left: 0;object-fit: contain;border: 6rpx solid #093763;box-sizing: border-box;
}#myCanvas {position: absolute;top: 0;left: 0;
}
</style>

3. 效果图

4. 解释

  • uni.createCanvasContext('myCanvas') 用于获取 Canvas 的绘图上下文。
  • ctx.setStrokeStyle('red') 和 ctx.setLineWidth(10) 用于设置描边颜色和宽度。
  • ctx.beginPath() 开始一个新的路径。
  • ctx.moveTo(points[0].x, points[0].y) 和 ctx.lineTo(points[i].x, points[i].y) 用于绘制线段。
  • ctx.closePath() 闭合路径,使之成为一个多边形。
  • ctx.stroke() 描边。
  • ctx.setFillStyle('rgba(30, 144, 255,0.5)') 和 ctx.fill() 用于填充多边形。
  • ctx.draw() 将所有绘图操作提交到 Canvas 上。

5. 坑

回显的时候,苦恼了很久,为什么点位已经传入,不能回显。后来发现,是draw方法需要加延时。

相关文章:

uni-app在image上绘制点位并回显

在 Uni-app 中绘制多边形可以通过使用 Canvas API 来实现。Uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;同时支持编译为 H5、小程序等多个平台。由于 Canvas 是 H5 和小程序中都支持的 API&#xff0c;所以通过 Canvas 绘制多边形是一个比较通用的方法。 1.…...

Comparator.comparing 排序注意

1. 对数字型字符串排序 List<String> values new ArrayList<>();values.add("10");values.add("6");values.add("20");values.add("30");values.add("50");//方法1 &#xff08;正确的排序方法&#xff09;//倒…...

PPO系列3 - PPO原理

On Policy: 采集数据的模型&#xff0c;和训练的模型&#xff0c;是同一个。缺点&#xff1a;慢&#xff0c;生成一批样本数据&#xff0c;训练一次&#xff0c;又要重新生成下一批。 Off Policy: 采集数据的模型&#xff0c;和训练的模型&#xff0c;不是同一个。有点&#xf…...

.idea

.idea/ 文件夹下的文件和目录主要用于存储 JetBrains IDE&#xff08;如 PyCharm、IntelliJ IDEA 等&#xff09;的项目配置。下面是一些常见文件和目录及其作用的详细介绍&#xff1a; 1. workspace.xml 用户界面布局&#xff1a;保存了IDE窗口布局&#xff0c;包括打开的文…...

单片机:实现呼吸灯(附带源码)

单片机实现呼吸灯详细解读 呼吸灯是一种常见的灯光效果&#xff0c;广泛应用于电子产品、汽车、家居照明等领域。其基本特性是通过逐渐增亮和减弱的方式&#xff0c;使得灯光呈现出“呼吸”的效果&#xff0c;给人一种平缓、舒适的视觉感受。在嵌入式系统中&#xff0c;呼吸灯…...

PostgreSQL数据库序列信息查询

PostgreSQL序列信息查询 说明&#xff1a; 在PostgreSQL数据库中序列和表都是序列的对象。 数据库中不应该存在孤儿序列&#xff0c;序列应该和表对应的字段绑定起来。绑定后删除表或表对应的字段后&#xff0c;序列会自动被删除。 创建测试表和序列 create table test_t(…...

【Linux】Nginx一个域名https一个地址配置多个项目【项目实战】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…...

Linux驱动开发(12):中断子系统–按键中断实验

本章我们以按键为例讲解在驱动程序中如何使用中断&#xff0c; 在学习本章之前建议先回顾一下关于中断相关的裸机部分相关章节&#xff0c; 这里主要介绍在驱动中如何使用中断&#xff0c;对于中断的概念及GIC中断控制器相关内容不再进行讲解。 本章配套源码和设备树插件位于“…...

代码随想录-算法训练营-番外(图论02:岛屿数量,岛屿的最大面积)

day02 图论part02 今日任务:岛屿数量,岛屿的最大面积 都是一个模子套出来的 https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html#思路往日任务: day01 图论part01 今日任务:图论理论基础/所有可到达的路径 代码随想录图论视频部分还没更新 https://programmercar…...

20 go语言(golang) - gin框架安装及使用(一)

一、简介 Gin是一个用Go语言编写的高性能Web框架&#xff0c;专注于构建快速、可靠的HTTP服务。它以其速度和简洁性而闻名&#xff0c;非常适合用于开发RESTful API。 高性能&#xff1a;Gin使用了httprouter进行路由管理&#xff0c;这是一个轻量级且非常快速的HTTP请求路由器…...

重生之我在学Vue--第3天 Vue 3 模板语法与指令

重生之我在学Vue–第3天 Vue 3 模板语法与指令 文章目录 重生之我在学Vue--第3天 Vue 3 模板语法与指令前言一、数据绑定1.1 单向绑定1.2 双向绑定 二、常用指令2.1 v-bind2.2 v-model2.3 v-if2.4 v-show2.5 v-for2.6 v-on 三、事件处理与表单绑定3.1 事件处理3.2 表单绑定 前言…...

电脑win11家庭版升级专业版和企业版相关事项

我的是零刻ser9&#xff0c;自带win11家庭版&#xff0c;但是我有远程操控需求&#xff0c;想用windows系统自带的远程连接功能&#xff0c;所以需要升级为专业版。然后在系统激活页面通过更改序列号方式&#xff0c;淘宝几块钱买了个序列号升级成功专业版了。但是&#xff0c;…...

docker 架构详解

Docker架构是基于客户端-服务器&#xff08;C/S&#xff09;模式的&#xff0c;包含多个关键组件&#xff0c;以确保容器化应用的高效构建、管理和运行。以下是对Docker架构的详细解析&#xff1a; Docker 架构概述 Docker 架构采用客户端-服务器&#xff08;C/S&#xff09;…...

tinyCam Pro 用于远程监控,控制和录制您的私人公共网络或IP摄像机

tinyCam Pro 是一款用于远程监控&#xff0c;控制和录制您的私人/公共网络或IP摄像机&#xff0c;视频编码器和具有500万次下载的CCTV摄像头的DVR。需使用3G/4G/WiFi连接和下载数据。 tinyCam Monitor Pro 可用于远程安全地监控您的宝宝、宠物、家庭、商业、交通和天气&#xf…...

Flask 验证码自动生成

Flask 验证码自动生成 想必验证码大家都有所了解&#xff0c;但是可以自己定义图片验证码&#xff0c;包含数字&#xff0c;英文以及数字计算&#xff0c;自动生成验证码。 生成图片以及结果 from captcha.image import ImageCaptchafrom PIL import Image from random impo…...

vmpwn小总结

前言&#xff1a; 好久没有更新博客了&#xff0c;关于vm的学习也是断断续续的&#xff0c;只见识了几道题目&#xff0c;但是还是想总结一下&#xff0c;所谓vmpwn就是把出栈&#xff0c;进栈&#xff0c;寄存器&#xff0c;bss段等单独申请一块空闲实现相关的功能&#xff0…...

开源密码管理器 Bitwarden 一站式管理所有密码以及 2FA

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 随着注册的平台越来越多&#xff0c;管理密码的难度也越来越高了。要是把密码都设置成一样的&#xff0c;担心哪天某个平台泄露被一锅端&#xff0c;而每个平台单独一个密码又不太好记&#xff0c;这时候就…...

标准体重计算API集成指南

标准体重计算API集成指南 引言 在当今数字化和健康意识日益增长的时代&#xff0c;开发人员和健康管理专业人士不断寻找创新的方法来促进用户的健康生活。标准体重计算是一个关键的健康指标&#xff0c;它可以帮助个人了解自己的身体状况&#xff0c;并为制定合适的饮食和运动…...

多个终端查看的history不一样,如何确保多个终端会话之间的 history 一致,减少历史记录差异

问题&#xff1a; 在使用 Linux 系统时&#xff0c;history 命令显示的历史记录通常是与当前终端会话相关的。这就意味着&#xff0c;如果你在多个终端中打开会话&#xff0c;它们显示的历史记录可能不完全相同。这个问题通常是由以下原因引起的&#xff1a; 原因&#xff1a…...

Spring Boot整合EasyExcel并行导出及Zip压缩下载

1. 项目依赖 首先&#xff0c;我们需要引入相关的依赖&#xff0c;包括 Spring Boot 和阿里巴巴的 EasyExcel 组件&#xff0c;此外还需要使用 Java 的 Zip 工具进行压缩操作。 <dependencies><!-- Spring Web --><dependency><groupId>org.springfr…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...