fix(tool): scale

This commit is contained in:
zhangheng
2026-04-21 20:47:15 +08:00
parent 8776ce4181
commit 7478788efd
2 changed files with 32 additions and 39 deletions

View File

@@ -329,10 +329,6 @@ const LabelPage = ({
const activeRasterScale = usePaperStore(
(state) => state.rasterScale[activeImage] ?? 1
)
const activeRasterSize = usePaperStore(
(state) => state.rasterSize[activeImage] ?? null
)
const currentGroup = usePaperStore((state) => state.group)
const {
setDescOperations,
metaOperation,
@@ -347,22 +343,6 @@ const LabelPage = ({
viewScale: scale,
})
}, [activeRasterScale, scale])
const scaleOffsets = useMemo(() => {
if (!currentGroup || !activeRasterSize?.[0] || !activeRasterSize?.[1]) {
return {
offsetX: 0,
offsetY: 0,
}
}
const displayedWidth = activeRasterSize[0] * displayedImageScale
const displayedHeight = activeRasterSize[1] * displayedImageScale
return {
offsetX: displayedWidth / 2 - currentGroup.position.x,
offsetY: displayedHeight / 2 - currentGroup.position.y,
}
}, [activeRasterSize, currentGroup, displayedImageScale])
const asyncGetProjectDetail = useCallback(async () => {
if (projectId) {
@@ -2727,8 +2707,6 @@ const LabelPage = ({
style={{ overflow: "hidden" }}>
<ScaleComponent
options={{
offsetX: scaleOffsets.offsetX,
offsetY: scaleOffsets.offsetY,
scale: displayedImageScale,
}}
mode="horizontal"
@@ -2736,8 +2714,6 @@ const LabelPage = ({
<Flex h="calc(100% - 32px)">
<ScaleComponent
options={{
offsetX: scaleOffsets.offsetX,
offsetY: scaleOffsets.offsetY,
scale: displayedImageScale,
}}
mode="vertical"

View File

@@ -4,8 +4,6 @@ import React, { useCallback, useEffect, useRef } from "react"
interface ScaleComponentProps {
options: {
offsetX: number
offsetY: number
scale: number
}
mode: "horizontal" | "vertical"
@@ -14,6 +12,7 @@ interface ScaleComponentProps {
const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
const { options, mode } = props
const canvasRef = useRef<HTMLCanvasElement>(null)
const FLOAT_EPSILON = 0.0000001
const getFixed = (sparsity: number) => {
const pointIdx = String(sparsity).indexOf(".")
@@ -22,8 +21,13 @@ const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
}
const isCloseToInteger = (num: number) => {
return Math.abs(num - Math.round(num)) < 0.0000001
return Math.abs(num - Math.round(num)) < FLOAT_EPSILON
}
const normalizeScaleValue = (num: number) => {
return Math.abs(num) < FLOAT_EPSILON ? 0 : num
}
const getSparsity = (scale: number) => {
if (scale <= 1) {
return Math.round(100 / scale)
@@ -63,20 +67,30 @@ const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
ctx.font = "12px serif"
ctx.beginPath()
const { offsetX, offsetY, scale } = options
const offset = mode === "horizontal" ? offsetX : offsetY
const { scale } = options
if (!Number.isFinite(scale) || scale <= 0) {
ctx.restore()
return
}
// 间隔
const sparsity = getSparsity(scale)
// 间隔内有多少条线
const part = 10
const pixelPerUnit = scale * sparsity
const gap = pixelPerUnit / part
const unitGap = sparsity / part
const fixed = getFixed(sparsity)
let index = offset % gap > 0 ? gap - (offset % gap) : -offset % gap
if (mode === "horizontal") {
ctx.translate(31.5, 0)
do {
const num = ((offset + index) / pixelPerUnit) * sparsity
const maxWidth = Math.max(0, w - 32)
for (
let tickIndex = 0;
tickIndex * gap <= maxWidth + FLOAT_EPSILON;
tickIndex += 1
) {
const index = tickIndex * gap
const num = normalizeScaleValue(tickIndex * unitGap)
if (isCloseToInteger(num / sparsity)) {
ctx.moveTo(index, h * 0.5)
ctx.lineTo(index, h)
@@ -87,12 +101,16 @@ const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
ctx.moveTo(index, h * 0.7)
ctx.lineTo(index, h)
}
index += gap
} while (index < w)
}
} else {
ctx.translate(0, 0.5)
do {
const num = ((offset + index) / pixelPerUnit) * sparsity
for (
let tickIndex = 0;
tickIndex * gap <= h + FLOAT_EPSILON;
tickIndex += 1
) {
const index = tickIndex * gap
const num = normalizeScaleValue(tickIndex * unitGap)
if (isCloseToInteger(num / sparsity)) {
ctx.moveTo(w * 0.5, index)
ctx.lineTo(w, index)
@@ -110,8 +128,7 @@ const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
ctx.moveTo(w * 0.7, index)
ctx.lineTo(w, index)
}
index += gap
} while (index < h)
}
}
ctx.closePath()
ctx.stroke()
@@ -129,7 +146,7 @@ const ScaleComponent: React.FC<ScaleComponentProps> = (props) => {
if (mode === "horizontal") {
return {
...baseStyles,
width: "100vw",
width: "100%",
height: "32px",
cursor: "col-resize",
}