Appearance
BizImageAnnotation 图片标注
底图上的框选 / 打点标注组件:tool="rect" 拖拽画框、tool="point" 点击落点,坐标按百分比存储随容器缩放自适应;选中标注浮层编辑名称 / 色系 / 一键填入常用词 / 删除;editable=false 纯展示回显。质检缺陷标记、安防圈人、巡检点位、医疗影像阅片等场景。
框选标注
划痕
在图上拖拽画框 → 点击标注可改名 / 换色 / 删除
拖拽画框 → 点击标注改名 / 换色 / 删除;
labels 快捷词一键填入。<script setup lang="ts">
/** 框选标注:拖拽画框、选中改名 / 换色 / 快捷词 / 删除;坐标百分比存储 */
import { ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
const annotations = ref<BizAnnotation[]>([
{ id: 'a1', type: 'rect', x: 18, y: 22, w: 26, h: 34, label: '划痕', tone: 'danger' },
])
const onChange = (): void => {
ElMessage.success(`当前 ${annotations.value.length} 处标注,数据已同步 v-model`)
}
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 8px; max-width: 640px">
<BizImageAnnotation
v-model="annotations"
src="https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=640&h=360&fit=crop&q=70"
tool="rect"
:labels="['划痕', '污渍', '变形', '合格']"
@add="onChange"
@remove="onChange"
/>
<div style="display: flex; gap: 8px; align-items: center; font-size: 12px; color: var(--el-text-color-secondary)">
<ElButton size="small" @click="annotations = []">清空标注</ElButton>
在图上拖拽画框 → 点击标注可改名 / 换色 / 删除
</div>
</div>
</template>
显示代码
打点标注
点击即落点;
getData() 提交点位快照(id / 坐标 / 名称 / 色系)。<script setup lang="ts">
/** 打点标注:点击即落点(巡检点位 / 安防圈人);提交展示数据快照 */
import { ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
const annotations = ref<BizAnnotation[]>([])
const pickerRef = ref<{ getData: () => BizAnnotation[] }>()
const submit = (): void => {
const data = pickerRef.value?.getData() ?? []
ElMessage.info(`共 ${data.length} 个点位,首点坐标 (${data[0]?.x.toFixed(1) ?? '-'}%, ${data[0]?.y.toFixed(1) ?? '-'}%)`)
}
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 8px; max-width: 640px">
<BizImageAnnotation
ref="pickerRef"
v-model="annotations"
src="https://images.unsplash.com/photo-1494972308805-463bc619d34e?w=640&h=360&fit=crop&q=70"
tool="point"
:labels="['摄像头', '出入口', '巡逻点']"
/>
<div>
<ElButton size="small" type="primary" @click="submit">提交点位数据</ElButton>
</div>
</div>
</template>
显示代码
纯展示回显
复核通过区
缺陷点 #17
待复检
editable="false" 渲染历史标注,点选查看名称(巡检 / 质检结果回显)。<script setup lang="ts">
/** 纯展示回显:editable=false 渲染历史标注,点选查看名称 */
import { ref } from 'vue'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
const annotations = ref<BizAnnotation[]>([
{ id: 'h1', type: 'rect', x: 12, y: 30, w: 22, h: 30, label: '复核通过区', tone: 'success' },
{ id: 'h2', type: 'point', x: 68, y: 62, label: '缺陷点 #17', tone: 'danger' },
{ id: 'h3', type: 'point', x: 82, y: 28, label: '待复检', tone: 'warning' },
])
</script>
<template>
<BizImageAnnotation
v-model="annotations"
src="https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?w=640&h=360&fit=crop&q=70"
:editable="false"
style="max-width: 640px"
/>
</template>
显示代码
语义色系
致命缺陷
严重缺陷
一般问题
复检通过
danger(致命)/ warning(严重)/ primary(一般)/ success(通过)——点击标注可在浮层中改档
tone 四档语义色表达缺陷 / 风险等级,选中浮层可切换。<script setup lang="ts">
/** 色系标注:tone 四档语义色(缺陷等级 / 风险等级),选中浮层可切换色系 */
import { ref } from 'vue'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
const annotations = ref<BizAnnotation[]>([
{ id: 'a1', type: 'rect', x: 8, y: 14, w: 22, h: 30, label: '致命缺陷', tone: 'danger' },
{ id: 'a2', type: 'rect', x: 38, y: 20, w: 20, h: 26, label: '严重缺陷', tone: 'warning' },
{ id: 'a3', type: 'rect', x: 64, y: 12, w: 24, h: 32, label: '一般问题', tone: 'primary' },
{ id: 'a4', type: 'point', x: 50, y: 78, label: '复检通过', tone: 'success' },
])
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 8px; max-width: 640px">
<BizImageAnnotation
v-model="annotations"
src="https://images.unsplash.com/photo-1583394838336-acd977736f90?w=640&h=360&fit=crop&q=70"
tool="rect"
/>
<div style="font-size: 12px; color: var(--el-text-color-secondary)">
danger(致命)/ warning(严重)/ primary(一般)/ success(通过)——点击标注可在浮层中改档
</div>
</div>
</template>
显示代码
混合标注
切换工具后直接在图上绘制
渗水区域
裂缝起点
检测仪表
框选与打点工具切换,区域缺陷 + 关键点位同图并存。
<script setup lang="ts">
/** 混合标注:radio 切换框选 / 打点工具,同一底图上区域缺陷 + 关键点位并存 */
import { ref } from 'vue'
import { ElRadioButton, ElRadioGroup } from 'element-plus'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
const tool = ref<'rect' | 'point'>('rect')
const annotations = ref<BizAnnotation[]>([
{ id: 'r1', type: 'rect', x: 14, y: 18, w: 30, h: 36, label: '渗水区域', tone: 'danger' },
{ id: 'p1', type: 'point', x: 72, y: 30, label: '裂缝起点', tone: 'warning' },
{ id: 'p2', type: 'point', x: 62, y: 70, label: '检测仪表', tone: 'primary' },
])
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 8px; max-width: 640px">
<div style="display: flex; gap: 12px; align-items: center">
<ElRadioGroup v-model="tool" size="small">
<ElRadioButton value="rect">框选区域</ElRadioButton>
<ElRadioButton value="point">点击打点</ElRadioButton>
</ElRadioGroup>
<span style="font-size: 12px; color: var(--el-text-color-secondary)">切换工具后直接在图上绘制</span>
</div>
<BizImageAnnotation
v-model="annotations"
src="https://images.unsplash.com/photo-1503387762-592deb58ef4e?w=640&h=360&fit=crop&q=70"
:tool="tool"
:labels="['渗水', '裂缝', '空鼓']"
/>
</div>
</template>
显示代码
事件审计
操作日志(最多保留 6 条)
add / remove / select 事件接入日志面板(标注操作留痕)。<script setup lang="ts">
/** 事件审计:add / remove / select 事件接入日志面板(标注操作留痕场景) */
import { ref } from 'vue'
import { ElButton, ElTag } from 'element-plus'
import { BizImageAnnotation } from 'vue3-ep-biz-lib'
import type { BizAnnotation } from 'vue3-ep-biz-lib'
interface LogEntry { id: number; text: string; tag: 'add' | 'remove' | 'select' }
const annotations = ref<BizAnnotation[]>([])
const logs = ref<LogEntry[]>([])
let seq = 0
const pushLog = (text: string, tag: LogEntry['tag']): void => {
seq += 1
logs.value = [{ id: seq, text, tag }, ...logs.value].slice(0, 6)
}
const onAdd = (item: BizAnnotation): void => {
pushLog(`新增标注「${item.label}」(${item.type === 'rect' ? '框' : '点'})`, 'add')
}
const onRemove = (id: string): void => {
pushLog(`删除标注 ${id}`, 'remove')
}
const onSelect = (id: string | null): void => {
if (id !== null) pushLog(`选中标注 ${id}`, 'select')
}
const clearAll = (): void => {
annotations.value = []
pushLog('清空全部标注', 'remove')
}
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 8px; max-width: 640px">
<BizImageAnnotation
v-model="annotations"
src="https://images.unsplash.com/photo-1565607737955-3b8a5e08c48e?w=640&h=360&fit=crop&q=70"
tool="rect"
:labels="['油污', '破损', '锈蚀']"
@add="onAdd"
@remove="onRemove"
@select="onSelect"
/>
<div style="display: flex; gap: 8px; align-items: flex-start">
<ElButton size="small" @click="clearAll">清空</ElButton>
<div style="flex: 1; min-height: 28px; border: 1px solid var(--el-border-color-lighter); border-radius: 4px; padding: 4px 8px; font-size: 12px">
<template v-if="logs.length > 0">
<div v-for="log in logs" :key="log.id" style="display: flex; gap: 6px; align-items: center; line-height: 22px">
<ElTag size="small" :type="log.tag === 'add' ? 'success' : log.tag === 'remove' ? 'danger' : 'info'">
{{ log.tag }}
</ElTag>
<span style="color: var(--el-text-color-regular)">{{ log.text }}</span>
</div>
</template>
<span v-else style="color: var(--el-text-color-secondary)">操作日志(最多保留 6 条)</span>
</div>
</div>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| src | string | —(必填) | 底图地址 |
| v-model | BizAnnotation[] | [] | 标注集合 |
| tool | 'rect' | 'point' | rect | 绘制工具 |
| editable | boolean | true | 允许绘制与编辑 |
| labels | string[] | [] | 快捷标注词 |
BizAnnotation
| 属性 | 类型 | 说明 |
|---|---|---|
| id | string | 标注标识 |
| type | 'rect' | 'point' | 标注类型 |
| x / y | number | point 中心 / rect 左上角,百分比 0-100 |
| w / h | number | rect 宽高百分比 |
| label | string | 标注名(框 / 点旁标签) |
| tone | 'primary' | 'success' | 'warning' | 'danger' | 色系(默认 danger) |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:modelValue | (annotations) | v-model 同步(增删改) |
| add / remove | (annotation) / (id) | 新增 / 删除标注 |
| select | (id | null) | 选中 / 取消选中 |
Expose
| 属性/方法 | 说明 |
|---|---|
| clear() | 清空全部标注 |
| getData() | 标注数据快照(提交用) |