vue-picture-bd-marker 图片添加标注
文档地址: https://vmarker.sagocloud.com/about/?spm=a2c6h.24755359.0.0.1b6441e4HwmruJ
实现效果: 
清空画布: this.$refs['aiPanel-editor'].clearData()
<template>
<div v-loading="loading" class="markBox">
<div class="imgbox" id="imgbox" ref="at">
<ui-marker
ref="aiPanel-editor"
class="ai-observer"
v-bind:uniqueKey="uuid"
:ratio="9/ 16"
@vmarker:onAnnoSelected="onAnnoSelected"
@vmarker:onAnnoAdded="onAnnoAdded"
@vmarker:onUpdated="onUpdated"
@vmarker:onReady="onReady"
@vmarker:onImageLoad="onImageLoad"
@vmarker:onDrawOne="onDrawOne(1)"
v-bind:readOnly="readOnly"
v-bind:imgUrl="currentImage"
>
</ui-marker>
</div>
<div class="btnBox">
<el-button class="diaWidth" @click="cancel" style="margin-right:20px">取消</el-button>
<el-button class="diaWidth" @click="toImage" type="primary">添加标注</el-button>
</div>
//选中标注区域在对应区域下展示select选择要标注的内容
<div v-if="markSelect" class="addMark" :style="{left: tranLeft, top: tranTop}">
<el-select v-model="text" allow-create filterable default-first-option @change="markChange" size="small" style="width:100%" placeholder="请选择">
<el-option
v-for="(item,index) in list"
:key="index"
:label="item.content"
:value="item.content">
</el-option>
</el-select>
</div>
</div>
</template>
import { AIMarker } from "Vue-Picture-BD-Marker";
import html2canvas from "html2canvas";
export default {
components: { "ui-marker": AIMarker, html2canvas },
data(){
uuid: "0da9130",
readOnly: false, //是否只读
currentImage: '',
blist:[],
text:'',
markSelect: false,
total: 0,
tranLeft: '',
tranTop: '',
},
watch:{
//选中select下拉框中的值时
text(val){
if(this.uuid!=''){
let blist = this.blist
blist.forEach(i => {
if(this.uuid == i.uuid){
this.$refs['aiPanel-editor'].getMarker().setTag({
tagName: this.text,
tag: "0x0001"
});
i.tagName = this.text
}
});
this.blist = blist
this.dialogVisible = false
this.uuid = ''this.text = ''
}
},
},
methods: {
//生成图片
toImage() {
// 没有标注提示
if(this.blist.length == 0){
this.$message({
message: '请选择标注',
type: "error",
});
return
}
this.loading = true
// 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等
html2canvas(this.$refs.at, {
backgroundColor: null,
useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
}).then((canvas) => {
let quality = 0.2;
let url = canvas.toDataURL("image/jpeg",quality);
this.htmlUrl = url;
let files = this.base64toFile(url)
let formData = new FormData();
formData.append("HotelId", this.hotelid);
formData.append("file", files);
// 把生成的base64位图片上传到服务器,生成在线图片地址
api_UploadImg(formData)
.then((res) => {
this.loading = false
})
.catch((error) => {
});
});
},
// base64转文件流
// html2canvas将div转成图片返回的是base64格式的,上传标注图片是需将base64转成文件流
base64toFile (dataurl, filename = 'file') {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime
})
},
onAnnoSelected(e) {
this.uuid = e.uuid
},
onAnnoAdded(e) {
// console.log("添加选框", e);
this.dialogVisible = true
this.uuid = e.uuid
//选中区域后展示select,在对应的区域下方
this.markSelect = true
this.tranLeft = Number(e.position.x.replace('%',''))/100 * document.querySelector('.imgbox').offsetWidth + 'px'
this.tranTop = Number(e.position.y1.replace('%',''))/100 * document.querySelector('.imgbox').offsetHeight + 20 + 'px'
//限制标注个数超过5个时隐藏select
if(this.total > 5){
this.markSelect = false
}
},
onUpdated(e) {
// console.log("选框位置或者标框属性发生改动", e);
this.blist = e
this.uuid = ''
this.text = ''
// 限制标注个数
this.total = 0
const markBox = document.getElementById('imgbox')
const markers = markBox.querySelectorAll('.annotation')
for (let i = 0; i < markers.length; i++) {
if (markers[i].clientWidth !== 0) {
this.total++
}
if (this.total > 5) {
this.$message.warning('最多只可标记五处!')
markers[i].remove()
}
}
//如果有重复的标注时新添加的标注覆盖已有的
let arr1 = []
let peon = e.reduce((cur,next) => {
let index = cur.findIndex(item=> item.tagName == next.tagName)
if(index != -1){
arr1.push(cur[index])
cur.splice(index, 1)
}
cur.push(next)
return cur;
},[])
this.blist = peon
e = peon
// 重复项新的替换旧的
for(var i = 0; i < markers.length; i++){
let arr = e.findIndex(item=>item.uuid == markers[i].getAttribute('data-uuid'))
// console.log(arr)
if(arr == -1){
markers[i].remove()
}
}
},

浙公网安备 33010602011771号