120 lines
3.2 KiB
TypeScript
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
|