插件VMarker:Vmarker是基于ui-picture-bd-marker的vue封裝,當Vmarker不足并存在現(xiàn)有要求或難以基于Vmarker擴展,此時可以繞過Vmarker進行擴展,直接使用ui-picture-bd-marker擴展即可。
使用方法:
1.安裝依賴
npm install vue-picture-bd-marker
2.在vue文件中引入Vmarker,為VMarker設定別名并作為組件引入
注:css樣式已經(jīng)在Vue-picture-BD-Marker中引用過了
<template>
<div>
<el-form
id="el-form"
ref="testForm"
label-position="left"
label-width="130px"
>
<el-form-item
v-for="(item,index) in testForm.sign"
:key="index"
:label="`標記${index + 1}`"
style="margin:20px 0"
>
<div :id="index" ref="imageWrapper" class="signBox">
<div class="sign-main" :class="`main${index}`">
<div v-show="currentImg.length === 0" class="placeHolder" @click="limitMarkRight(index)" />
<ui-marker
v-if="currentImg.length !== 0"
:ref="`aiPanel-editor${index}`"
class="ai-observer"
:class="`cs${index}`"
:img-url="currentImg[index]"
:read-only="readOnly[index]"
@vmarker:onUpdated="onUpdated(index)"
@vmarker:onImageLoad="onImageLoad(index)"
@vmarker:onDrawOne="onDrawOne(index)"
@vmarker:onReady="onReady(index)"
@vmarker:selectOne="selectOne"
@click.native="changeBack(index)"
/>
<div class="sign-footer
<el-button type="primary" size="mini" @click="handleImgChange(index)">重新編輯</el-button>
</div>
</div>
</div>
</el-form-item>
<el-form-item align="center">
<el-button@click="submitForm">確認創(chuàng)建</el-button>
</el-form-item>
</el-form>
</div>
</template>
import {Aimarker} from 'Vue-Picture-BD-Marker'
export default {
components: { 'ui-marker': AiMarker },
data() {
testForm: {
sign : ['圖片地址1', '圖片地址2', '圖片地址3']
},
currentImg: [],
readOnly: []
}
}
3.操作說明
1.加載圖片
用屬性imgUrl可以加載url或者base64的圖片
<ui-marker ref="aiPanel-editor" class="ai-observer"
v-bind:uniqueKey="uuid"
:ratio="16/9"
:imgUrl="url或base64">
</ui-marker>
當圖片加載完成后,vmarker會發(fā)送一個onImageLoad 的事件,即this.$emit('vmarker:omImageLoad',rawData, uuid),其中,rawData包含圖片的原始寬高和現(xiàn)有寬高
2.標注
當在圖片上畫矩形框后,需要對該標注進行備注,以指示該標注代表的含義。此時可以使用vmarker控件的getMarker方法獲取marker實例,再通過marker的實例方法setTag針對選中的矩形框進行標注。 marker可以通過控件的getMarker方法進行獲取。vmarker控件自身也有setTag方法。
setTag接收一個名稱或一個對象
this.$refs['aiPanel-editor'].getMarker().setTag({
tagName: "小蜜蜂",
tag: "0x0001"
});
或
this.$refs['aiPanel-editor'].setTag({
tagName: "小蜜蜂",
tag: "0x0001"
});
3.獲取元數(shù)據(jù)
getData獲取的數(shù)據(jù)為一個數(shù)組
this.$refs['aiPanel-editor'].getMarker().getData();
獲取的數(shù)據(jù)
[
{
tag: "id04",
tagName: "蜜蜂",
position: {
x: "41.026%",
y: "22.678%",
x1: "53.790000000000006%",
y1: "40.496%"
},
uuid: "42BA3F7114C8B50D"
}
]
4.加載標注數(shù)據(jù)
renderData操作會將數(shù)據(jù)標注到圖上,這意味著多次執(zhí)行renderData之后,會出現(xiàn)多次標注。 如果需要清空畫布,可以調(diào)用marker.clearData()進行清空。
renderData(data,wh)參數(shù)為標注數(shù)據(jù)組成的數(shù)組,基準寬高【可選】
this.$refs['aiPanel-editor'].getMarker().renderData([
{
tag: "id04",
tagName: "蜜蜂",
position: {
x: "41.026%",
x1: "53.790000000000006%",
y: "22.678%",
y1: "40.496%"
},
uuid: "5559A20B25712D9D"
}
]);
清除數(shù)據(jù)
this.$refs['aiPanel-editor'].getMarker().clearData();
5.屬性說明
readOnly
為true時不可編輯,僅做展示
ratio
圖形的寬高比,默認為16/9, 圖為當設置為4 / 3的效果
好像無效
uniqueKey
識別控件唯一性,當頁面存在多個控件時需要區(qū)分。默認未設置。
6.事件
vmarker:onUpdated
@vmarker:onUpdated = onUpdated(index)
當標注框位置或者標框?qū)傩园l(fā)生改動時回調(diào),參數(shù)為data【標注數(shù)據(jù)】, uniqueKey
可以在這個事件里改變標注的css樣式
onUpdated(index) {
const box = document.getElementById(index)
const div = box.querySelector('.annotation')
const annotate = box.querySelector('.annotate.vmr-ai-raw-image-mask')
div.style.borderRadius = '50%'
div.style.borderColor = 'rgb(255,0,0)'
div.style.borderWidth = '2px'
annotate.addEventListener('click', () => {
const children = div.querySelectorAll('.resize-dot')
children.forEach(item => { item.classList.add('hidden') })
})
div.addEventListener('click', e => {
e.stopPropagation()
})
},
@vmarker:onDrawOne= 'onDrawOne(index)'
當畫完一個標注框時回調(diào),參數(shù)為data【標注數(shù)據(jù)】, uniqueKey
onDrawOne(index) {
this.total = 0
this.$refs[ `aiPanel-editor${index}` ][0].getMarker().setTag({
tagName: '',
tag: ''
})
//當你想限制標記個數(shù)時
const markBox = document.getElementById(index)
const markers = markBox.querySelectorAll('.annotation')
for (let i = 0; i < markers.length; i++) {
if (markers[i].clientWidth !== 0) {
this.total++
}
if (this.total >= 2) {
this.$message.warning('此圖只可標記一處,若想標記第二處請點擊加號按鈕')
markers[i].remove()
}
}
},
uniqueKey 識別控件唯一性,當頁面存在多個控件時需要區(qū)分 默認值:無
readOnly 是否只作顯示 默認值:false
width 寬(單位:像素、百分比) 默認值:100%
ratio 控件寬高比例 默認值:16/9
imgUrl 圖片url 默認值:無
vmarker:onImageLoad 圖片加載完成后回調(diào),不包含data:image格式?;卣{(diào)參數(shù),data={rawW,rawH,currentW,currentH}
vmarker:onReady 當控件準備完成后回調(diào),參數(shù)為uniqueKey
vmarker:onDrawOne 當畫完一個標注框時回調(diào),參數(shù)為data【標注數(shù)據(jù)】, uniqueKey
vmarker:onSelect 當選中圖片上的標注框時回調(diào),參數(shù)為data【標注數(shù)據(jù)】, uniqueKey
vmarker:onUpdated 當標注框位置或者標框?qū)傩园l(fā)生改動時回調(diào),參數(shù)為data【標注數(shù)據(jù)】, uniqueKey
vmarker:onDataRendered 當標注框主動渲染數(shù)據(jù)后時回調(diào),參數(shù)為uniqueKey
7.修改標記區(qū)域的寬高比和圖片一樣
方法:
adjustmentRatio(index) {
const div = document.querySelector(`.cs${index}`)
const dom1 = div.querySelector('.vmr-ai-raw-image-mask')
const dom2 = div.querySelector('.vmr-g-image')
const dom3 = div.querySelector('.vmr-ai-raw-image')
const img = new Image()
img.onload = function() {
const h = img.naturalHeight
const w = img.naturalWidth
this.cal = w / h
const x = div.clientWidth / this.cal
div.style.height = x + 'px'
dom1.style.height = x + 'px'
dom2.style.height = x + 'px'
dom3.style.height = x + 'px'
}
img.src = dom3.src
},
watch監(jiān)聽當currentImg改變時觸發(fā)方法
watch: {
currentImg: {
handler(newValue, oldValue) {
for (let i = 0; i < newValue.length; i++) {
this.$nextTick(() => {
// this.changeBack(i)
this.adjustmentRatio(i)
})
}
},
deep: true
}
}