前端Vue3实现图片标点两种方式总结
作者:hjhcos
前言
公司的业务要求可以在图片的位置上面进行标点,然后在现场对汽车桌椅可以实现按照标点进行质量检测。
技术栈
图像标点
- 将画布覆盖在图像上;
- 将图像画在画布上;
目前采用的是画布覆盖在图像上,画布覆盖在图像上这种方式也有两种:
- 将画布的大小调整为图像渲染的大小;
- 将画布分解为颗粒,分散在图像上面;
图像基本概念
图像大小有两个概念:固定尺寸和渲染的大小。
固定尺寸就是图像真实的分辨率大小;
渲染的大小则是图像在网页渲染后的分辨率大小;
因此画布按照图像大小绘制的话,可能存在渲染的大小并非和图像真实的大小相同。
效果图
方式一:画布全局覆盖图像
- 根据图像大小绘制画布
- 监控图像或画布点击
- 绘制圆点和序号
1.编写前端显示代码
<div style="position: relative"> <img id="img-1" src="/Img/image/1530088404487.jpg" @click="handleClickImg1"/> <canvas id="canvas-1" style="position: absolute; top: 0; left: 0;" @click="handleClickImg1" /> </div>
这里定义了 handleClickImg1
点击事件是用来记录鼠标在图片点击的坐标,从而在其上面做一些操作,这里分别在图片或画布上面都做点击监控,是因为第一次画布加载渲染的大小和后面展示在页面的大小不一致。
画布使用相对位置布局 position: absolute;
并且配置以图片左上角顶点为原点向右往下绘制画布 top: 0; left: 0;
,是为了保证画布与图像完全重叠在一起,从而坐标可以一一对应上。
2.配置基本数据
// 图片基本信息 const image = ref(); const imageWidth = ref(0); const imageHeight = ref(0); // 画布 const canvas = ref(); const ctx = ref(); // 记录点击点 const proQualityList1 = ref([]);
定义一些参数来接受或后续使用,详情请看代码注释。
3.根据图像渲染大小绘制画布
/** * 根据图像大小绘制画布 */ async function drawImageToCanvas() { // 获取图片元素 image.value = document.getElementById('img-1'); // 获取图片在页面渲染的大小 imageWidth.value = image.value.clientWidth; imageHeight.value = image.value.clientHeight; // 获取画布元素 canvas.value = document.getElementById('canvas-1'); // 设置画布的大小于图片渲染大小一致 canvas.value.width = imageWidth.value; canvas.value.height = imageHeight.value; // 获取二维画布 ctx.value = canvas.value.getContext("2d"); }
**Tip:**个人喜好把独立函数定义为异步,异步函数调试可能会进不了断点。
drawImageToCanvas
异步函数主要是用来获取页面渲染的图片,并将图片渲染的大小获取到,将其值赋值给画布的宽高,从而把画布与图片的大小一致,从而进行绘画。
4.在画布绘圆
/** * 在画布绘制圆点 */ const drawOriginPoint = (x, y, color) => { const radius = 8; ctx.value.beginPath(); ctx.value.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.value.fillStyle = color; ctx.value.fill(); };
5.在画布绘序号
/** * 在画布绘制序号 */ const drawSnPoint = (sn, x, y, color) => { ctx.value.font = '14px Arial'; ctx.value.fillStyle = color; ctx.value.textAlign = 'center'; ctx.value.textBaseline = 'middle'; ctx.value.fillText(sn, x, y); };
6.处理图片点击
/** * 图片点击:处理画布全局覆盖 */ function handleClickImg(e) { drawImageToCanvas(); let dataset = e.target.dataset proQualityList1.value.push({ sn: proQualityList1.value.length + 1, positionX: e.offsetX || e.layerX, positionY: e.offsetY || e.layerY, }); for(let item of proQualityList1.value) { drawOriginPoint(item.positionX, item.positionY, '#f00'); drawSnPoint(item.sn, item.positionX, item.positionY, '#fff'); } }
方式二:画布分散覆盖图像
- 监控图像或画布点击
- 根据点击坐标创建画布
- 绘制圆点和序号
1.编写前端显示代码
<div style="position: relative" id="canvas-2"> <img id="img-2" src="/Img/image/1530088404487.jpg" @click="handleClickImg2"/> </div>
这里定义了 handleClickImg2
点击事件是用来记录鼠标在图片点击的坐标,从而在其上面做一些操作,这里只在图片上面做了点击监控,从而保证可以分散创建画布。
这里的思路是通过相对布局将画布都挂载到父元素上面,因此这里为父元素定义了唯一id id="canvas-2"
。
2.配置基本数据
// 图片基本信息 const image = ref(); const imageWidth = ref(0); const imageHeight = ref(0); // 画布 const canvas = ref(); const ctx = ref(); // 记录点击点 const proQualityList2 = ref([]);
定义一些参数来接受或后续使用,详情请看代码注释。
3.在画布绘圆
/** * 在画布绘制圆点 */ const drawOriginPoint = (x, y, color) => { const radius = 8; ctx.value.beginPath(); ctx.value.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.value.fillStyle = color; ctx.value.fill(); };
4.在画布绘序号
/** * 在画布绘制序号 */ const drawSnPoint = (sn, x, y, color) => { ctx.value.font = '14px Arial'; ctx.value.fillStyle = color; ctx.value.textAlign = 'center'; ctx.value.textBaseline = 'middle'; ctx.value.fillText(sn, x, y); };
5.创建画布
/** * 创建画布 */ function createCanvas(sn, x, y, color) { let canvas = document.createElement('canvas'); // 设置Canvas的固定宽度和高度 canvas.width = 24; canvas.height = 24; // 设置Canvas的样式 canvas.style.position = 'absolute'; canvas.style.top = `${y}px`; canvas.style.left = `${x}px`; let ctx = canvas.getContext('2d'); // 圆点半径,可以根据需要调整 const radius = 8; ctx.beginPath(); ctx.arc(canvas.width / 2, canvas.height / 2, radius, 0, 2 * Math.PI, false); // 设置填充颜色 ctx.fillStyle = color[0]; ctx.fill(); // 文字样式设置 ctx.font = '14px Arial'; // 设置填充颜色 ctx.fillStyle = color[1]; // 设置文本对齐方式(左、中、右) ctx.textAlign = 'center'; // 设置文本基线(上、中、下等) ctx.textBaseline = 'middle'; // 绘制数字 ctx.fillText(sn, canvas.width / 2, canvas.height / 2); // 获取要插入Canvas的容器 let container = document.getElementById(`canvas-2`); // @ts-ignore 将Canvas添加到页面中 container.appendChild(canvas); }
这里最大的特点就是通过设置Canvas的样式来将一小块画布放在图片上面:
// 设置Canvas的样式 canvas.style.position = 'absolute'; canvas.style.top = `${y}px`; canvas.style.left = `${x}px`;
6.处理图片点击
/** * 图片点击:处理画布分散覆盖 */ function handleClickImg2(e) { let dataset = e.target.dataset proQualityList2.value.push({ sn: proQualityList.value.length + 1, positionX: e.offsetX || e.layerX, positionY: e.offsetY || e.layerY, }); createCanvas(proQualityList2.value.length, e.offsetX || e.layerX, e.offsetY || e.layerY, ['#f00', '#fff']) }
总结
到此这篇关于前端Vue3实现图片标点两种方式的文章就介绍到这了,更多相关前端Vue3图片标点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!