插件VMarker:Vmarker是基于ui-picture-bd-marker的vue封装,当Vmarker不足并存在现有要求或难以基于Vmarker扩展,此时可以绕过Vmarker进行扩展,直接使用ui-picture-bd-marker扩展即可。
使用方法:
1.安装依赖
npm install vue-picture-bd-marker
2.在vue文件中引入Vmarker,为VMarker设定别名并作为组件引入
注:css样式已经在Vue-picture-BD-Marker中引用过了
确认创建
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的图片
当图片加载完成后,vmarker会发送一个onImageLoad 的事件,即this.$emit('vmarker:omImageLoad',rawData, uuid),其中,rawData包含图片的原始宽高和现有宽高
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.获取元数据
getData获取的数据为一个数组
this.$refs['aiPanel-editor'].getMarker().getData();
获取的数据
[
{
tag: "id04",
tagName: "蜜蜂",
position: {
x: "41.026%",
y: "22.678%",
x1: "53.790000000000006%",
y1: "40.496%"
},
uuid: "42BA3F7114C8B50D"
}
]
4.加载标注数据
renderData操作会将数据标注到图上,这意味着多次执行renderData之后,会出现多次标注。 如果需要清空画布,可以调用marker.clearData()进行清空。
renderData(data,wh)参数为标注数据组成的数组,基准宽高【可选】
this.$refs['aiPanel-editor'].getMarker().renderData([
{
tag: "id04",
tagName: "蜜蜂",
position: {
x: "41.026%",
x1: "53.790000000000006%",
y: "22.678%",
y1: "40.496%"
},
uuid: "5559A20B25712D9D"
}
]);
清除数据
this.$refs['aiPanel-editor'].getMarker().clearData();
5.属性说明
readOnly
为true时不可编辑,仅做展示
ratio
图形的宽高比,默认为16/9, 图为当设置为4 / 3的效果
好像无效
uniqueKey
识别控件唯一性,当页面存在多个控件时需要区分。默认未设置。
6.事件
vmarker:onUpdated
@vmarker:onUpdated = onUpdated(index)
当标注框位置或者标框属性发生改动时回调,参数为data【标注数据】, 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)'
当画完一个标注框时回调,参数为data【标注数据】, uniqueKey
onDrawOne(index) {
this.total = 0
this.$refs[ `aiPanel-editor${index}` ][0].getMarker().setTag({
tagName: '',
tag: ''
})
//当你想限制标记个数时
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 识别控件唯一性,当页面存在多个控件时需要区分 默认值:无
readOnly 是否只作显示 默认值:false
width 宽(单位:像素、百分比) 默认值:100%
ratio 控件宽高比例 默认值:16/9
imgUrl 图片url 默认值:无
vmarker:onImageLoad 图片加载完成后回调,不包含data:image格式。回调参数,data={rawW,rawH,currentW,currentH}
vmarker:onReady 当控件准备完成后回调,参数为uniqueKey
vmarker:onDrawOne 当画完一个标注框时回调,参数为data【标注数据】, uniqueKey
vmarker:onSelect 当选中图片上的标注框时回调,参数为data【标注数据】, uniqueKey
vmarker:onUpdated 当标注框位置或者标框属性发生改动时回调,参数为data【标注数据】, uniqueKey
vmarker:onDataRendered 当标注框主动渲染数据后时回调,参数为uniqueKey
7.修改标记区域的宽高比和图片一样
方法:
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监听当currentImg改变时触发方法
watch: {
currentImg: {
handler(newValue, oldValue) {
for (let i = 0; i < newValue.length; i++) {
this.$nextTick(() => {
// this.changeBack(i)
this.adjustmentRatio(i)
})
}
},
deep: true
}
}