0


【前端】Vue3实现图片标点

前言

公司的业务要求可以在图片的位置上面进行标点,然后在现场对汽车桌椅可以实现按照标点进行质量检测。

技术栈

图像标点

  1. 将画布覆盖在图像上;
  2. 将图像画在画布上;

目前采用的是画布覆盖在图像上,画布覆盖在图像上这种方式也有两种:

  1. 将画布的大小调整为图像渲染的大小;
  2. 将画布分解为颗粒,分散在图像上面;

图像基本概念

图像大小有两个概念:固定尺寸和渲染的大小。
固定尺寸就是图像真实的分辨率大小;
渲染的大小则是图像在网页渲染后的分辨率大小;
因此画布按照图像大小绘制的话,可能存在渲染的大小并非和图像真实的大小相同。
在这里插入图片描述

效果图

在这里插入图片描述

方式一:画布全局覆盖图像

  1. 根据图像大小绘制画布
  2. 监控图像或画布点击
  3. 绘制圆点和序号

1.编写前端显示代码

<divstyle="position: relative"><imgid="img-1"src="/Img/image/1530088404487.jpg"@click="handleClickImg1"/><canvasid="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.根据图像渲染大小绘制画布

/**
 * 根据图像大小绘制画布
 */asyncfunctiondrawImageToCanvas(){// 获取图片元素
    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.在画布绘圆

/**
 * 在画布绘制圆点
 */constdrawOriginPoint=(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.在画布绘序号

/**
 * 在画布绘制序号
 */constdrawSnPoint=(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.处理图片点击

/**
 * 图片点击:处理画布全局覆盖
 */functionhandleClickImg(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. 监控图像或画布点击
  2. 根据点击坐标创建画布
  3. 绘制圆点和序号

1.编写前端显示代码

<divstyle="position: relative"id="canvas-2"><imgid="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.在画布绘圆

/**
 * 在画布绘制圆点
 */constdrawOriginPoint=(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.在画布绘序号

/**
 * 在画布绘制序号
 */constdrawSnPoint=(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.创建画布

/**
 * 创建画布
 */functioncreateCanvas(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.处理图片点击

/**
 * 图片点击:处理画布分散覆盖
 */functionhandleClickImg2(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'])}
标签: 前端 vue

本文转载自: https://blog.csdn.net/hjh_cos/article/details/139679243
版权归原作者 hjhcos 所有, 如有侵权,请联系我们删除。

“【前端】Vue3实现图片标点”的评论:

还没有评论