前端Vue3實現(xiàn)圖片標點兩種方式總結
前言
公司的業(yè)務要求可以在圖片的位置上面進行標點,然后在現(xiàn)場對汽車桌椅可以實現(xiàn)按照標點進行質(zhì)量檢測。
技術棧
圖像標點
- 將畫布覆蓋在圖像上;
- 將圖像畫在畫布上;
目前采用的是畫布覆蓋在圖像上,畫布覆蓋在圖像上這種方式也有兩種:
- 將畫布的大小調(diào)整為圖像渲染的大??;
- 將畫布分解為顆粒,分散在圖像上面;
圖像基本概念
圖像大小有兩個概念:固定尺寸和渲染的大小。
固定尺寸就是圖像真實的分辨率大小;
渲染的大小則是圖像在網(wǎng)頁渲染后的分辨率大小;
因此畫布按照圖像大小繪制的話,可能存在渲染的大小并非和圖像真實的大小相同。

效果圖

方式一:畫布全局覆蓋圖像
- 根據(jù)圖像大小繪制畫布
- 監(jiān)控圖像或畫布點擊
- 繪制圓點和序號
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 點擊事件是用來記錄鼠標在圖片點擊的坐標,從而在其上面做一些操作,這里分別在圖片或畫布上面都做點擊監(jiān)控,是因為第一次畫布加載渲染的大小和后面展示在頁面的大小不一致。
畫布使用相對位置布局 position: absolute; 并且配置以圖片左上角頂點為原點向右往下繪制畫布 top: 0; left: 0;,是為了保證畫布與圖像完全重疊在一起,從而坐標可以一一對應上。
2.配置基本數(shù)據(jù)
// 圖片基本信息 const image = ref(); const imageWidth = ref(0); const imageHeight = ref(0); // 畫布 const canvas = ref(); const ctx = ref(); // 記錄點擊點 const proQualityList1 = ref([]);
定義一些參數(shù)來接受或后續(xù)使用,詳情請看代碼注釋。
3.根據(jù)圖像渲染大小繪制畫布
/**
* 根據(jù)圖像大小繪制畫布
*/
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:**個人喜好把獨立函數(shù)定義為異步,異步函數(shù)調(diào)試可能會進不了斷點。
drawImageToCanvas 異步函數(shù)主要是用來獲取頁面渲染的圖片,并將圖片渲染的大小獲取到,將其值賦值給畫布的寬高,從而把畫布與圖片的大小一致,從而進行繪畫。
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');
}
}
方式二:畫布分散覆蓋圖像
- 監(jiān)控圖像或畫布點擊
- 根據(jù)點擊坐標創(chuàng)建畫布
- 繪制圓點和序號
1.編寫前端顯示代碼
<div style="position: relative" id="canvas-2">
<img id="img-2" src="/Img/image/1530088404487.jpg" @click="handleClickImg2"/>
</div>
這里定義了 handleClickImg2 點擊事件是用來記錄鼠標在圖片點擊的坐標,從而在其上面做一些操作,這里只在圖片上面做了點擊監(jiān)控,從而保證可以分散創(chuàng)建畫布。
這里的思路是通過相對布局將畫布都掛載到父元素上面,因此這里為父元素定義了唯一id id="canvas-2"。
2.配置基本數(shù)據(jù)
// 圖片基本信息 const image = ref(); const imageWidth = ref(0); const imageHeight = ref(0); // 畫布 const canvas = ref(); const ctx = ref(); // 記錄點擊點 const proQualityList2 = ref([]);
定義一些參數(shù)來接受或后續(xù)使用,詳情請看代碼注釋。
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.創(chuàng)建畫布
/**
* 創(chuàng)建畫布
*/
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');
// 圓點半徑,可以根據(jù)需要調(diào)整
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';
// 繪制數(shù)字
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實現(xiàn)圖片標點兩種方式的文章就介紹到這了,更多相關前端Vue3圖片標點內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue-cli3配置favicon.ico和title的流程
這篇文章主要介紹了vue-cli3配置favicon.ico和title的流程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
基于Vue?+?ElementUI實現(xiàn)可編輯表格及校驗
這篇文章主要給大家介紹了基于Vue?+?ElementUI?實現(xiàn)可編輯表格及校驗,文中有詳細的代碼講解和實現(xiàn)思路,講解的非常詳細,有需要的朋友可以參考下2023-08-08

