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

235 lines
6.4 KiB
TypeScript

import paper from "paper"
import { create } from "zustand"
import { usePaperStore } from "./usePaperStore"
import { useTopToolsStore } from "./useTopToolsStore"
interface SupportStore {
masks: paper.Path.Rectangle[]
pointTexts: paper.PointText[]
selectedCircles: paper.Path.Circle[]
bufferPaths: paper.Path[]
handleMask: (path: paper.Path | paper.Item | paper.CompoundPath) => void
removeMaskById: (id: number) => void
removeMaskByIds: (id: number[]) => void
clearMasks: () => void
handleText: (path: paper.Path | paper.Item | paper.CompoundPath) => void
clearTexts: () => void
handleCircles: (path: paper.Path | paper.CompoundPath | null) => void
clearCircles: () => void
handleBufferPaths: (path: paper.Path | paper.CompoundPath | null) => void
clearBufferPaths: () => void
clearAll: () => void
}
export const usePaperSupportStore = create<SupportStore>((set) => ({
masks: [],
pointTexts: [],
selectedCircles: [],
bufferPaths: [],
handleMask: (path) =>
set((state) => {
let newMasks = state.masks
if (newMasks.length) {
newMasks = newMasks.filter((mask) => {
if (mask.data.id !== path.data.id) {
return true
} else {
mask.remove()
return false
}
})
}
let bounds = path.bounds
let mask = new paper.Path.Rectangle({
parent: usePaperStore.getState().group!,
point: [bounds.left, bounds.top],
size: [bounds.width, bounds.height],
fillColor: path.data.fillColor,
strokeColor: path.data.strokeColor,
strokeWidth: path.data.strokeWidth || 1,
// opacity: 0.3,
strokeScaling: false,
})
mask.data = {
type: "mask",
id: path.data.id,
operationId: path.data.operationId,
}
newMasks.push(mask)
return {
...state,
masks: newMasks,
}
}),
removeMaskById: (id) =>
set((state) => {
let newMasks = state.masks.filter((mask) => {
if (mask.data.id !== id) {
return true
} else {
mask.remove()
return false
}
})
return {
...state,
masks: newMasks,
}
}),
removeMaskByIds: (ids) =>
set((state) => {
let newMasks = state.masks.filter((mask) => {
if (!ids.includes(mask.data.id)) {
return true
} else {
mask.remove()
return false
}
})
return {
...state,
masks: newMasks,
}
}),
clearMasks: () =>
set((state) => {
if (state.masks.length) {
state.masks.forEach((mask) => mask.remove())
}
return {
...state,
masks: [],
}
}),
handleText: (path) =>
set((state) => {
if (state.pointTexts.length) {
state.pointTexts.forEach((item) => item.remove())
}
let newTexts: any[] = []
// let circleItems = usePaperStore.getState().group!.getItems({
// data: { type: "circle" },
// });
const currentScaling = usePaperStore.getState().group!.scaling.x
const newScale = useTopToolsStore.getState().scale / currentScaling
let currentPointTexts = (path as paper.Path)?.segments.map(
(item, index) => {
// let text = circleItems.find((circle) => circle.contains(item.point))
// ?.data.text;
let text = index + 1
let pointText = new paper.PointText({
parent: usePaperStore.getState().group!,
point: item.point,
content: text?.toString(),
justification: "right",
fillColor: path?.data?.strokeColor,
// fontSize: 12,
data: {
type: "text",
id: path.data.id,
operationId: path.data.operationId,
},
strokeScaling: false,
// scaling: usePaperStore.getState().group!.scaling,
})
pointText.scale(newScale / currentScaling)
return pointText
}
)
currentPointTexts.forEach((currentPointText) => {
newTexts.push(currentPointText)
})
return {
...state,
pointTexts: newTexts,
}
}),
clearTexts: () =>
set((state) => {
if (state.pointTexts.length) {
state.pointTexts.forEach((pointText) => pointText.remove())
}
return {
...state,
pointTexts: [],
}
}),
handleCircles: (path) =>
set((state) => {
if (state.selectedCircles.length) {
state.selectedCircles.forEach((circle) => circle.remove())
}
let newCircles: any[] = []
path &&
path instanceof paper.Path &&
path.segments.forEach((segment) => {
let circle = usePaperStore
.getState()
.getClickedCircle(
segment.point,
segment.index,
path.data.id,
path.data.blankColor
)
newCircles.push(circle)
})
return {
...state,
selectedCircles: newCircles,
}
}),
clearCircles: () =>
set((state) => {
if (state.selectedCircles.length) {
state.selectedCircles.forEach((circle) => circle.remove())
}
return {
...state,
selectedCircles: [],
}
}),
handleBufferPaths: (path) =>
set((state) => {
if (state.bufferPaths.length) {
state.bufferPaths.forEach((bufferPath) => bufferPath.remove())
}
let newPaths: any[] = []
path &&
path instanceof paper.Path &&
path.segments.forEach((segment) => {
let bufferPath = usePaperStore
.getState()
.getBuffPath(
segment,
segment.index,
path.data.id,
path.data.blankColor
)
if (bufferPath) newPaths.push(bufferPath)
})
return {
...state,
bufferPaths: newPaths,
}
}),
clearBufferPaths: () =>
set((state) => {
if (state.bufferPaths.length) {
state.bufferPaths.forEach((bufferPath) => bufferPath.remove())
}
return {
...state,
bufferPaths: [],
}
}),
clearAll: () => {
usePaperSupportStore.getState().clearMasks()
usePaperSupportStore.getState().clearTexts()
usePaperSupportStore.getState().clearCircles()
usePaperSupportStore.getState().clearBufferPaths()
},
}))