Files
labelimage/components/label/components/ScaleToolContainer.tsx
2026-03-10 18:20:50 +08:00

120 lines
3.2 KiB
TypeScript

import { ActionIcon, Flex, NumberInput, Stack, Text } from "@mantine/core"
import { IconMinus, IconPlus, IconRefresh } from "@tabler/icons-react"
import paper from "paper"
import { useMemo } from "react"
import { useKeyEventStore } from "../store"
import { usePaperStore } from "../usePaperStore"
import { useTopToolsStore } from "../useTopToolsStore"
const ScaleToolContainer = () => {
const { scale, setScale } = useTopToolsStore()
const { setFocusInput } = useKeyEventStore()
const displayNumber = useMemo(() => {
return Number((scale * 100).toFixed(0))
}, [scale])
const setCurrentScale = (n: number) => {
const currentScale = n / 100
const group = usePaperStore.getState().group
if (!group) return
group.scaling = new paper.Point(currentScale, currentScale)
setScale(currentScale)
}
const handleReset = () => {
const group = usePaperStore.getState().group
if (!group) return
const rasterList = group.getItems({
data: {
name: "pic",
},
})
if (!rasterList || !rasterList.length) return
const currentRaster = rasterList[0]
group.position = currentRaster.position
setCurrentScale(100)
}
const handleEnter = (e: any) => {
const num = Number(e.target.value)
if (isNaN(num)) return
if (num > 9999 || num < 0) return
setCurrentScale(num)
}
return (
<Stack
w={60}
h="100%"
align="center"
justify="flex-end"
gap="xs"
ml={4}
pb="xs"
style={{
borderLeft:
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
borderRight:
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
}}>
<ActionIcon
variant="default"
size="lg"
radius="sm"
onClick={handleReset}
style={{ width: 32, height: 32 }}>
<IconRefresh size={20} />
</ActionIcon>
<ActionIcon
variant="default"
size="lg"
radius="sm"
onClick={() => {
setCurrentScale(
displayNumber + 10 <= 9999 ? displayNumber + 10 : 9999
)
}}
style={{ width: 32, height: 32 }}>
<IconPlus size={20} />
</ActionIcon>
<Flex align="center" justify="center" w="100%">
<NumberInput
w={40}
size="xs"
variant="unstyled"
value={displayNumber}
max={9999}
min={1}
styles={{ input: { textAlign: "center", padding: 0 } }}
onKeyDown={(e) => {
if (e.key === "Enter") {
handleEnter(e)
}
}}
onFocus={() => {
setFocusInput(true)
}}
onBlur={() => {
setFocusInput(false)
}}
hideControls
/>
<Text size="xs">%</Text>
</Flex>
<ActionIcon
variant="default"
size="lg"
radius="sm"
onClick={() => {
setCurrentScale(displayNumber - 10 >= 0 ? displayNumber - 10 : 1)
}}
style={{ width: 32, height: 32 }}>
<IconMinus size={20} />
</ActionIcon>
</Stack>
)
}
export default ScaleToolContainer