最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端Vue3實(shí)現(xiàn)圖片標(biāo)點(diǎn)兩種方式總結(jié)

 更新時(shí)間:2024年11月27日 09:06:31   作者:hjhcos  
這篇文章主要介紹了如何使用Vue3和Ant?Design?Vue4.x實(shí)現(xiàn)圖像標(biāo)點(diǎn)和質(zhì)量檢測(cè)功能,文章詳細(xì)描述了兩種方式,每種方式都包括前端顯示代碼、配置基本數(shù)據(jù)、繪制圓點(diǎn)和序號(hào)以及處理圖片點(diǎn)擊的步驟,需要的朋友可以參考下

前言

公司的業(yè)務(wù)要求可以在圖片的位置上面進(jìn)行標(biāo)點(diǎn),然后在現(xiàn)場(chǎng)對(duì)汽車桌椅可以實(shí)現(xiàn)按照標(biāo)點(diǎn)進(jìn)行質(zhì)量檢測(cè)。

技術(shù)棧

圖像標(biāo)點(diǎn)

  • 將畫布覆蓋在圖像上;
  • 將圖像畫在畫布上;

目前采用的是畫布覆蓋在圖像上,畫布覆蓋在圖像上這種方式也有兩種:

  • 將畫布的大小調(diào)整為圖像渲染的大?。?/li>
  • 將畫布分解為顆粒,分散在圖像上面;

圖像基本概念

圖像大小有兩個(gè)概念:固定尺寸和渲染的大小。

固定尺寸就是圖像真實(shí)的分辨率大小;

渲染的大小則是圖像在網(wǎng)頁渲染后的分辨率大??;

因此畫布按照?qǐng)D像大小繪制的話,可能存在渲染的大小并非和圖像真實(shí)的大小相同。

效果圖

方式一:畫布全局覆蓋圖像

  • 根據(jù)圖像大小繪制畫布
  • 監(jiān)控圖像或畫布點(diǎn)擊
  • 繪制圓點(diǎn)和序號(hào)

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 點(diǎn)擊事件是用來記錄鼠標(biāo)在圖片點(diǎn)擊的坐標(biāo),從而在其上面做一些操作,這里分別在圖片或畫布上面都做點(diǎn)擊監(jiān)控,是因?yàn)榈谝淮萎嫴技虞d渲染的大小和后面展示在頁面的大小不一致。

畫布使用相對(duì)位置布局 position: absolute; 并且配置以圖片左上角頂點(diǎn)為原點(diǎn)向右往下繪制畫布 top: 0; left: 0;,是為了保證畫布與圖像完全重疊在一起,從而坐標(biāo)可以一一對(duì)應(yīng)上。

2.配置基本數(shù)據(jù)

// 圖片基本信息
const image = ref();
const imageWidth = ref(0);
const imageHeight = ref(0);
// 畫布
const canvas = ref();
const ctx = ref();
// 記錄點(diǎn)擊點(diǎn)
const proQualityList1 = ref([]);

定義一些參數(shù)來接受或后續(xù)使用,詳情請(qǐng)看代碼注釋。

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');
    // 設(shè)置畫布的大小于圖片渲染大小一致
    canvas.value.width = imageWidth.value;
    canvas.value.height = imageHeight.value;
    // 獲取二維畫布
    ctx.value = canvas.value.getContext("2d");
}

**Tip:**個(gè)人喜好把獨(dú)立函數(shù)定義為異步,異步函數(shù)調(diào)試可能會(huì)進(jìn)不了斷點(diǎn)。

drawImageToCanvas 異步函數(shù)主要是用來獲取頁面渲染的圖片,并將圖片渲染的大小獲取到,將其值賦值給畫布的寬高,從而把畫布與圖片的大小一致,從而進(jìn)行繪畫。

4.在畫布繪圓

/**
 * 在畫布繪制圓點(diǎn)
 */
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.在畫布繪序號(hào)

/**
 * 在畫布繪制序號(hào)
 */
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.處理圖片點(diǎn)擊

/**
 * 圖片點(diǎn)擊:處理畫布全局覆蓋
 */
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)控圖像或畫布點(diǎn)擊
  • 根據(jù)點(diǎn)擊坐標(biāo)創(chuàng)建畫布
  • 繪制圓點(diǎn)和序號(hào)

1.編寫前端顯示代碼

<div style="position: relative" id="canvas-2">
    <img id="img-2" src="/Img/image/1530088404487.jpg" @click="handleClickImg2"/>
</div>

這里定義了 handleClickImg2 點(diǎn)擊事件是用來記錄鼠標(biāo)在圖片點(diǎn)擊的坐標(biāo),從而在其上面做一些操作,這里只在圖片上面做了點(diǎn)擊監(jiān)控,從而保證可以分散創(chuàng)建畫布。

這里的思路是通過相對(duì)布局將畫布都掛載到父元素上面,因此這里為父元素定義了唯一id id="canvas-2"。

2.配置基本數(shù)據(jù)

// 圖片基本信息
const image = ref();
const imageWidth = ref(0);
const imageHeight = ref(0);
// 畫布
const canvas = ref();
const ctx = ref();
// 記錄點(diǎn)擊點(diǎn)
const proQualityList2 = ref([]);

定義一些參數(shù)來接受或后續(xù)使用,詳情請(qǐng)看代碼注釋。

3.在畫布繪圓

/**
 * 在畫布繪制圓點(diǎn)
 */
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.在畫布繪序號(hào)

/**
 * 在畫布繪制序號(hào)
 */
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');
    // 設(shè)置Canvas的固定寬度和高度
    canvas.width = 24;
    canvas.height = 24;
    // 設(shè)置Canvas的樣式
    canvas.style.position = 'absolute';
    canvas.style.top = `${y}px`;
    canvas.style.left = `${x}px`;
    let ctx = canvas.getContext('2d');
    // 圓點(diǎn)半徑,可以根據(jù)需要調(diào)整
    const radius = 8;
    ctx.beginPath();
    ctx.arc(canvas.width / 2, canvas.height / 2, radius, 0, 2 * Math.PI, false);
    // 設(shè)置填充顏色
    ctx.fillStyle = color[0];
    ctx.fill();
    // 文字樣式設(shè)置
    ctx.font = '14px Arial';
    // 設(shè)置填充顏色
    ctx.fillStyle = color[1];
    // 設(shè)置文本對(duì)齊方式(左、中、右)
    ctx.textAlign = 'center';
    // 設(shè)置文本基線(上、中、下等)
    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);
}

這里最大的特點(diǎn)就是通過設(shè)置Canvas的樣式來將一小塊畫布放在圖片上面:

// 設(shè)置Canvas的樣式
canvas.style.position = 'absolute';
canvas.style.top = `${y}px`;
canvas.style.left = `${x}px`;

6.處理圖片點(diǎn)擊

/**
 * 圖片點(diǎn)擊:處理畫布分散覆蓋
 */
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'])
}

總結(jié) 

到此這篇關(guān)于前端Vue3實(shí)現(xiàn)圖片標(biāo)點(diǎn)兩種方式的文章就介紹到這了,更多相關(guān)前端Vue3圖片標(biāo)點(diǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue3實(shí)現(xiàn)組件級(jí)基類的多種方法

    Vue3實(shí)現(xiàn)組件級(jí)基類的多種方法

    vue3提供了 mixins和extends,但是嘗試之后發(fā)現(xiàn)這兩種方法只支持純OptionAPI,設(shè)置的data會(huì)被識(shí)別,但是設(shè)置的setup里return 的 reactive,完全無效,setup也沒有被執(zhí)行,這篇文章主要介紹了Vue3實(shí)現(xiàn)組件級(jí)基類的幾種方法,需要的朋友可以參考下
    2023-04-04
  • vue綁定class的三種方法

    vue綁定class的三種方法

    這篇文章主要介紹了vue綁定class的三種方法,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下
    2020-12-12
  • 詳解vue的雙向綁定原理及實(shí)現(xiàn)

    詳解vue的雙向綁定原理及實(shí)現(xiàn)

    這篇文章主要介紹了vue雙向綁定原理及實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析

    關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析

    這篇文章主要介紹了關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析,在過去傳統(tǒng)開發(fā)中,頁面渲染任務(wù)是由服務(wù)端完成的,那么Nuxt是如何渲染的呢,需要的朋友可以參考下
    2023-04-04
  • vue-cli3配置favicon.ico和title的流程

    vue-cli3配置favicon.ico和title的流程

    這篇文章主要介紹了vue-cli3配置favicon.ico和title的流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 基于Vue?+?ElementUI實(shí)現(xiàn)可編輯表格及校驗(yàn)

    基于Vue?+?ElementUI實(shí)現(xiàn)可編輯表格及校驗(yàn)

    這篇文章主要給大家介紹了基于Vue?+?ElementUI?實(shí)現(xiàn)可編輯表格及校驗(yàn),文中有詳細(xì)的代碼講解和實(shí)現(xiàn)思路,講解的非常詳細(xì),有需要的朋友可以參考下
    2023-08-08
  • 淺析Vue中渲染函數(shù)的使用

    淺析Vue中渲染函數(shù)的使用

    在Vue中,渲染函數(shù)是一種用于動(dòng)態(tài)生成組件的函數(shù),可以將組件的模板代碼編寫為JavaScript代碼,并在運(yùn)行時(shí)進(jìn)行渲染,下面我們就來看看它的具體用法吧
    2023-08-08
  • VUE?mixin?使用示例詳解

    VUE?mixin?使用示例詳解

    混入mixin提供了一種非常靈活的方式,來分發(fā)Vue組件中的可復(fù)用功能,一個(gè)混入對(duì)象可以包含任意組件選項(xiàng),接下來通過本文給大家介紹VUE?mixin?使用,需要的朋友可以參考下
    2022-08-08
  • Vue項(xiàng)目中使用Bootstrap

    Vue項(xiàng)目中使用Bootstrap

    這篇文章介紹了Vue項(xiàng)目中使用Bootstrap的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Vue 源碼分析之 Observer實(shí)現(xiàn)過程

    Vue 源碼分析之 Observer實(shí)現(xiàn)過程

    這篇文章主要介紹了 Vue 源碼分析之 Observer實(shí)現(xiàn)過程,Observer 最主要的作用就是實(shí)現(xiàn)了touch -Data(getter) - Collect as Dependency這段過程,也就是依賴收集的過程,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-03-03

最新評(píng)論

台南市| 宜宾市| 虞城县| 南汇区| 郓城县| 北安市| 灵璧县| 光泽县| 阳春市| 青神县| 平塘县| 海丰县| 建湖县| 尉氏县| 乌海市| 五原县| 宝鸡市| 邵东县| 阳城县| 汉源县| 黄山市| 河东区| 广汉市| 哈尔滨市| 穆棱市| 弥勒县| 威远县| 远安县| 化隆| 武强县| 广汉市| 葫芦岛市| 临高县| 神农架林区| 博乐市| 林州市| 耒阳市| 师宗县| 苗栗市| 保德县| 如皋市|