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 开发所有前端应用的框架,同时支持编译为 H5、小程序等多个平台。由于 Canvas 是 H5 和小程序中都支持的 API,所以通过 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 (正确的排序方法)//倒…...
PPO系列3 - PPO原理
On Policy: 采集数据的模型,和训练的模型,是同一个。缺点:慢,生成一批样本数据,训练一次,又要重新生成下一批。 Off Policy: 采集数据的模型,和训练的模型,不是同一个。有点…...
.idea
.idea/ 文件夹下的文件和目录主要用于存储 JetBrains IDE(如 PyCharm、IntelliJ IDEA 等)的项目配置。下面是一些常见文件和目录及其作用的详细介绍: 1. workspace.xml 用户界面布局:保存了IDE窗口布局,包括打开的文…...
单片机:实现呼吸灯(附带源码)
单片机实现呼吸灯详细解读 呼吸灯是一种常见的灯光效果,广泛应用于电子产品、汽车、家居照明等领域。其基本特性是通过逐渐增亮和减弱的方式,使得灯光呈现出“呼吸”的效果,给人一种平缓、舒适的视觉感受。在嵌入式系统中,呼吸灯…...
PostgreSQL数据库序列信息查询
PostgreSQL序列信息查询 说明: 在PostgreSQL数据库中序列和表都是序列的对象。 数据库中不应该存在孤儿序列,序列应该和表对应的字段绑定起来。绑定后删除表或表对应的字段后,序列会自动被删除。 创建测试表和序列 create table test_t(…...
【Linux】Nginx一个域名https一个地址配置多个项目【项目实战】
👨🎓博主简介 🏅CSDN博客专家 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入!…...
Linux驱动开发(12):中断子系统–按键中断实验
本章我们以按键为例讲解在驱动程序中如何使用中断, 在学习本章之前建议先回顾一下关于中断相关的裸机部分相关章节, 这里主要介绍在驱动中如何使用中断,对于中断的概念及GIC中断控制器相关内容不再进行讲解。 本章配套源码和设备树插件位于“…...
代码随想录-算法训练营-番外(图论02:岛屿数量,岛屿的最大面积)
day02 图论part02 今日任务:岛屿数量,岛屿的最大面积 都是一个模子套出来的 https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html#思路往日任务: day01 图论part01 今日任务:图论理论基础/所有可到达的路径 代码随想录图论视频部分还没更新 https://programmercar…...
20 go语言(golang) - gin框架安装及使用(一)
一、简介 Gin是一个用Go语言编写的高性能Web框架,专注于构建快速、可靠的HTTP服务。它以其速度和简洁性而闻名,非常适合用于开发RESTful API。 高性能:Gin使用了httprouter进行路由管理,这是一个轻量级且非常快速的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,自带win11家庭版,但是我有远程操控需求,想用windows系统自带的远程连接功能,所以需要升级为专业版。然后在系统激活页面通过更改序列号方式,淘宝几块钱买了个序列号升级成功专业版了。但是,…...
docker 架构详解
Docker架构是基于客户端-服务器(C/S)模式的,包含多个关键组件,以确保容器化应用的高效构建、管理和运行。以下是对Docker架构的详细解析: Docker 架构概述 Docker 架构采用客户端-服务器(C/S)…...
tinyCam Pro 用于远程监控,控制和录制您的私人公共网络或IP摄像机
tinyCam Pro 是一款用于远程监控,控制和录制您的私人/公共网络或IP摄像机,视频编码器和具有500万次下载的CCTV摄像头的DVR。需使用3G/4G/WiFi连接和下载数据。 tinyCam Monitor Pro 可用于远程安全地监控您的宝宝、宠物、家庭、商业、交通和天气…...
Flask 验证码自动生成
Flask 验证码自动生成 想必验证码大家都有所了解,但是可以自己定义图片验证码,包含数字,英文以及数字计算,自动生成验证码。 生成图片以及结果 from captcha.image import ImageCaptchafrom PIL import Image from random impo…...
vmpwn小总结
前言: 好久没有更新博客了,关于vm的学习也是断断续续的,只见识了几道题目,但是还是想总结一下,所谓vmpwn就是把出栈,进栈,寄存器,bss段等单独申请一块空闲实现相关的功能࿰…...
开源密码管理器 Bitwarden 一站式管理所有密码以及 2FA
本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 随着注册的平台越来越多,管理密码的难度也越来越高了。要是把密码都设置成一样的,担心哪天某个平台泄露被一锅端,而每个平台单独一个密码又不太好记,这时候就…...
标准体重计算API集成指南
标准体重计算API集成指南 引言 在当今数字化和健康意识日益增长的时代,开发人员和健康管理专业人士不断寻找创新的方法来促进用户的健康生活。标准体重计算是一个关键的健康指标,它可以帮助个人了解自己的身体状况,并为制定合适的饮食和运动…...
多个终端查看的history不一样,如何确保多个终端会话之间的 history 一致,减少历史记录差异
问题: 在使用 Linux 系统时,history 命令显示的历史记录通常是与当前终端会话相关的。这就意味着,如果你在多个终端中打开会话,它们显示的历史记录可能不完全相同。这个问题通常是由以下原因引起的: 原因:…...
Spring Boot整合EasyExcel并行导出及Zip压缩下载
1. 项目依赖 首先,我们需要引入相关的依赖,包括 Spring Boot 和阿里巴巴的 EasyExcel 组件,此外还需要使用 Java 的 Zip 工具进行压缩操作。 <dependencies><!-- Spring Web --><dependency><groupId>org.springfr…...
GC 怎么判定“该回收谁”:GC Roots、可达性分析、四种引用与回收算法
很多人学 GC 的痛点是: 名词一堆:标记清除、复制、标记整理、分代但一旦你真遇到“内存回不去”,你又不知道该从哪里解释 这篇把 GC 的主线拆成两条: 先判定谁活谁死(可达性分析)再决定怎么回收(…...
从“能源黑洞“到“热源工厂“:数据中心废热回收的技术革命与效率重构
数据中心废热回收技术的演进,不仅是技术层面的创新,更是能源理念的深刻变革。它标志着数据中心从单纯的"能源消耗者"向"能源产消者"转型,从"算力工厂"向"能源枢纽"升级。 在全球数字化浪潮的推动…...
HOW - 撰写前端技术方案
文章目录 一份完整前端技术方案结构 项目背景 & 目标 技术选型 架构设计(核心) 模块划分 数据流设计(很重要) 接口设计(API 对接) 状态管理方案 性能优化方案 安全方案 工程化方案 测试方案 部署 & CI/CD 风险 & 预案 总结 加分 图示或表格 功能到工程的考量…...
LeetCode:121. 买卖股票的最佳时机
简介 题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/ 解决方式:数组 贪心算法 这是作者学习众多大神的思路进行解题的步骤,很推荐大家解题的时候去看看题解里面大佬们的思路、想法! 推荐看…...
DeepSeek-OCR镜像部署教程:无需conda/pip,开箱即用Streamlit方案
DeepSeek-OCR镜像部署教程:无需conda/pip,开箱即用Streamlit方案 你是不是经常遇到这样的烦恼:收到一张图片文档,里面既有文字又有表格,想要提取里面的内容,只能一个字一个字地敲?或者表格结构…...
探索DiceBear 30+头像风格:从Adventurer到Pixel Art的创意之旅
探索DiceBear 30头像风格:从Adventurer到Pixel Art的创意之旅 【免费下载链接】dicebear DiceBear is an avatar library for designers and developers. 🌍 项目地址: https://gitcode.com/gh_mirrors/di/dicebear DiceBear是一个专为设计师和开…...
StructBERT情感分类模型在旅游评论分析中的创新应用
StructBERT情感分类模型在旅游评论分析中的创新应用 1. 引言 "这家酒店的海景房真的太棒了!早上醒来就能看到日出,就是WiFi信号有点不太稳定..." 如果你在旅游平台看到这样的评论,会怎么判断游客的整体体验?是正面还…...
CAD设计文档智能处理:Nanbeige 4.1-3B解析工程图纸说明文本
CAD设计文档智能处理:Nanbeige 4.1-3B解析工程图纸说明文本 1. 引言 如果你在制造业、建筑设计或者机械工程领域工作过,一定对CAD图纸旁边那几十页甚至上百页的技术说明文档不陌生。密密麻麻的文字里,藏着材料规格、工艺要求、公差标准、装…...
DeepAnalyze从零开始教程:不装CUDA、不配环境,纯容器化文本分析系统搭建
DeepAnalyze从零开始教程:不装CUDA、不配环境,纯容器化文本分析系统搭建 1. 这不是另一个“跑通就行”的AI工具,而是一个能真正读懂文字的分析助手 你有没有过这样的经历:手头有一份30页的行业报告,老板说“下午三点…...
【科研经验贴】全要素生产率估计:从原理到Stata实操,我踩过的坑都在这了
一、什么是全要素生产率?为啥要估计它?很多刚接触实证研究的同学可能会问:“全要素生产率到底是个啥?我为啥要估计它?”其实全要素生产率(Total Factor Productivity, TFP)就是“除了劳动力、资…...
