235 lines
6.4 KiB
TypeScript
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()
|
|
},
|
|
}))
|