feat(circle): change size

This commit is contained in:
zhangheng
2026-04-15 11:04:42 +08:00
parent d3d9e8385b
commit 72b1dacf1c
4 changed files with 133 additions and 39 deletions

View File

@@ -18,7 +18,7 @@ import { useKeyboardStore } from "./useKeyBoardStore"
import { useOtherToolsStore } from "./useOtherToolsStore"
import { usePaperSupportStore } from "./usePaperSupportStore"
import { useRightToolsStore } from "./useRightToolsStore"
import { useTopToolsStore } from "./useTopToolsStore"
import { DEFAULT_NODE_SIZE, useTopToolsStore } from "./useTopToolsStore"
import { safeClone } from "./utils/clone"
interface ContinuePolygonTarget {
@@ -183,6 +183,7 @@ interface PaperState {
setContinuePolygonTarget: (target: ContinuePolygonTarget | null) => void
beginContinuePolygonDraft: () => boolean
setLoadingData: (flag: boolean) => void
refreshNodeVisualSize: () => void
resizeGhostRequestToken: number
requestResizeGhost: () => void
}
@@ -328,6 +329,7 @@ const PAPER_CONTEXT_HIT_TYPES = [
"pathBuff",
"pathCircle",
] as const
const LEGACY_PAPER_NODE_DIAMETER = 6
const isPaperObjectType = (type: unknown) =>
typeof type === "string" &&
@@ -339,6 +341,39 @@ const isPaperContextHitType = (type: unknown) =>
type as (typeof PAPER_CONTEXT_HIT_TYPES)[number]
)
const getPaperNodeDiameter = () => {
const configuredDiameter = useTopToolsStore.getState().nodeSize
return Number.isFinite(configuredDiameter)
? Math.round(configuredDiameter)
: DEFAULT_NODE_SIZE
}
const getPaperNodeRadius = () => getPaperNodeDiameter() / 2
const getPaperNodeScaleFactor = () => {
const currentScaling = usePaperStore.getState().group?.scaling.x || 1
const newScale = useTopToolsStore.getState().scale / currentScaling
return newScale / currentScaling
}
const syncPaperCircleDiameter = (circle: paper.Path) => {
const nextDiameter = getPaperNodeDiameter()
const currentDiameter =
Number(circle.data?.diameter) || LEGACY_PAPER_NODE_DIAMETER
if (
Number.isFinite(currentDiameter) &&
currentDiameter > 0 &&
Math.abs(currentDiameter - nextDiameter) > 0.001
) {
circle.scale(nextDiameter / currentDiameter)
}
circle.data = Object.assign({}, circle.data, {
diameter: nextDiameter,
})
}
const getPaperCursorByMode = (
mode: PaperState["mode"] = usePaperStore.getState().mode
) => {
@@ -529,6 +564,7 @@ const createPointCircleForPath = (
imageId: path.data.imageId,
operationId: path.data.operationId,
text: index + 1,
diameter: getPaperNodeDiameter(),
fillColor: path.data.blankColor,
strokeColor: path.data.strokeColor,
})
@@ -562,6 +598,7 @@ const syncPointCirclesWithPath = (path: paper.Path) => {
imageId: path.data.imageId,
operationId: path.data.operationId,
text: index + 1,
diameter: getPaperNodeDiameter(),
fillColor: path.data.blankColor,
strokeColor: path.data.strokeColor,
})
@@ -1014,6 +1051,19 @@ export const usePaperStore = create<PaperState>((set) => ({
...state,
loadingData: flag,
})),
refreshNodeVisualSize: () => {
const group = usePaperStore.getState().group
if (!group) return
;(
group.getItems({
match: (item: paper.Item) =>
item instanceof paper.Path &&
["circle", "pathCircle"].includes(item.data?.type || ""),
}) as paper.Path[]
).forEach((circle) => {
syncPaperCircleDiameter(circle)
})
},
requestResizeGhost: () =>
set((state: PaperState) => ({
...state,
@@ -5427,6 +5477,7 @@ export const usePaperStore = create<PaperState>((set) => ({
const newScale = useTopToolsStore.getState().scale / currentScaling
myCircle.scale(newScale / currentScaling)
myCircle.data = Object.assign({ type: "circle", ...option }, data)
syncPaperCircleDiameter(myCircle)
myCircle.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
if (e.event && e.event.button === 2) {
if (
@@ -5844,6 +5895,7 @@ export const usePaperStore = create<PaperState>((set) => ({
id: number,
color: any
) => {
const nodeDiameter = getPaperNodeDiameter()
let circle: paper.Path.Circle = new paper.Path.Circle(
Object.assign(
{ parent: usePaperStore.getState().group!, center: point },
@@ -5851,12 +5903,13 @@ export const usePaperStore = create<PaperState>((set) => ({
fillColor: color,
// center: point,
strokeColor: usePaperStore.getState().toolOption?.strokeColor,
radius: 3,
radius: getPaperNodeRadius(),
strokeScaling: false,
},
{
data: {
type: "circle",
diameter: nodeDiameter,
fillColor: color,
strokeColor: usePaperStore.getState().toolOption?.strokeColor,
imageId: useBottomToolsStore.getState().activeImage,
@@ -5868,9 +5921,7 @@ export const usePaperStore = create<PaperState>((set) => ({
}
)
)
const currentScaling = usePaperStore.getState().group!.scaling.x
const newScale = useTopToolsStore.getState().scale / currentScaling
circle.scale(newScale / currentScaling)
circle.scale(getPaperNodeScaleFactor())
circle.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
if (e.event && e.event.button === 2) {
if (
@@ -6051,8 +6102,7 @@ export const usePaperStore = create<PaperState>((set) => ({
id: number,
color: any
) => {
const currentScaling = usePaperStore.getState().group!.scaling.x
const newScale = useTopToolsStore.getState().scale / currentScaling
const nodeDiameter = getPaperNodeDiameter()
let circle: paper.Path.Circle = new paper.Path.Circle(
Object.assign(
{ parent: usePaperStore.getState().group!, center: point },
@@ -6060,15 +6110,16 @@ export const usePaperStore = create<PaperState>((set) => ({
fillColor: color,
// center: point,
strokeColor: "#FFF",
radius: 3,
strokeWidth: 2,
radius: getPaperNodeRadius(),
strokeScaling: false,
},
{
data: { index, type: "pathCircle", id },
data: { index, type: "pathCircle", id, diameter: nodeDiameter },
}
)
)
circle.scale(newScale / currentScaling)
circle.scale(getPaperNodeScaleFactor())
circle.onMouseEnter = (_e: any) => {
hoveredPathCircleInfo = {
id,