Files
labelmain/components/label/useRenderTag.ts
2026-02-03 18:05:47 +08:00

166 lines
5.7 KiB
TypeScript

import paper from "paper"
import { useLabelStore } from "./store"
import { useBottomToolsStore } from "./useBottomToolsStore"
import { usePaperStore } from "./usePaperStore"
import { useTopToolsStore } from "./useTopToolsStore"
export const removeTagTexts = (id?: number) => {
const group = usePaperStore.getState().group
if (!group) return
const items = id
? group.getItems({ data: { id, type: "tag" } })
: group.getItems({ data: { type: "tag" } })
items.forEach((item) => item.remove())
}
const useRenderTag = () => {
const renderTag = () => {
const dataMap = useLabelStore.getState().label
const activeImage = useBottomToolsStore.getState().activeImage
const group = usePaperStore.getState().group
const visible = useTopToolsStore.getState().showTags
const configs = useTopToolsStore.getState().showTagsConfigs
// 清空之前渲染的标签
removeTagTexts()
for (const [imageId, categoryMap] of dataMap) {
if (imageId === activeImage) {
for (const [categoryId, labelList] of categoryMap) {
let category = useTopToolsStore
.getState()
.objectOperations.find(
(item) => item.category_id.toString() === categoryId
)!
const { label_class } = category
labelList.forEach(([id, _d, detail]) => {
const path = usePaperStore.getState().getItemById(id)
if (path) {
const bounds = path.bounds
let pos = [bounds.left, bounds.top - 6]
let pathData = path.data
let content = ``
if (configs.includes("ID"))
content += `${id}${
path.data.parentGroupId ? `@${path.data.parentGroupId}` : ""
}`
if (configs.includes("类别")) content += ` ${label_class}`
if (
detail.sub_attributes &&
Object.keys(detail.sub_attributes).length
) {
Object.keys(detail.sub_attributes).forEach((key) => {
if (configs.includes("子属性")) content += ` ${key}:`
if (configs.includes("属性值"))
content += `${detail.sub_attributes[key]};`
})
}
// 文本
const text = new paper.PointText(pos)
text.set({
content,
fontSize: 12,
fontWeight: "bold",
fillColor: "black",
data: {
id,
type: "tag",
tag_category: "text",
},
parent: group,
visible,
})
// 文本框
const textMask = new paper.Path.Rectangle(text.bounds)
textMask.set({
fillColor: pathData.fillColor,
strokeColor: pathData.strokeColor,
strokeWidth: 1,
strokeScaling: false,
data: {
id,
type: "tag",
tag_category: "text_mask",
},
parent: group,
visible,
})
// 标注对象外接框
const mask = new paper.Path.Rectangle(bounds)
mask.set({
strokeColor: pathData.strokeColor,
strokeWidth: 2,
strokeScaling: false,
data: {
id,
type: "tag",
tag_category: "mask",
},
parent: group,
visible: visible && configs.includes("外框"),
})
// 标注对象点id
if (path instanceof paper.CompoundPath) {
let index = 1
path.children.forEach((child) => {
const segments = (child as paper.Path).segments
segments.forEach((segment) => {
let pointTextPosition = [
segment.point.x - 10,
segment.point.y + 5,
]
const pointText = new paper.PointText(pointTextPosition)
pointText.set({
content: index,
fontSize: 12,
fontWeight: "bold",
fillColor: pathData.strokeColor,
data: {
id,
type: "tag",
tag_category: "point_text",
},
parent: group,
visible: visible && configs.includes("点ID"),
})
index++
})
})
} else {
const segments = (path as paper.Path).segments
segments.forEach((segment, index) => {
let pointTextPosition = [
segment.point.x - 10,
segment.point.y + 5,
]
const pointText = new paper.PointText(pointTextPosition)
pointText.set({
content: index + 1,
fontSize: 12,
fontWeight: "bold",
fillColor: pathData.strokeColor,
data: {
id,
type: "tag",
tag_category: "point_text",
},
parent: group,
visible: visible && configs.includes("点ID"),
})
})
}
}
})
}
}
}
}
return {
renderTag,
}
}
export default useRenderTag