Files
labelimage/components/label/components/AssistShapeComponent.tsx
2026-04-03 20:40:04 +08:00

78 lines
1.9 KiB
TypeScript

"use client"
import React, {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useRef,
} from "react"
interface AssistShapeComponentProps {
size: number
}
const AssistShapeComponent = (
props: AssistShapeComponentProps,
ref: React.Ref<unknown> | undefined
) => {
const { size } = props
const canvasRef = useRef<HTMLCanvasElement>(null)
const drawAssistShape = useCallback(
(centerX: number, centerY: number) => {
const canvas = canvasRef.current
const ctx = canvas?.getContext("2d")
if (!canvas || !ctx) return
const radius = Math.max(1, size)
const side = radius * 2
const left = centerX - radius
const top = centerY - radius
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.beginPath()
ctx.strokeStyle = "#EF4444"
ctx.lineWidth = 2
ctx.setLineDash([6, 4])
ctx.strokeRect(left, top, side, side)
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)
ctx.stroke()
},
[size]
)
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const rect = canvas.getBoundingClientRect()
drawAssistShape(rect.width / 2, rect.height / 2)
}, [drawAssistShape])
const updateAssistShape = (event: { clientX: number; clientY: number }) => {
const canvas = canvasRef.current
if (!canvas) return
const rect = canvas.getBoundingClientRect()
const centerX = event.clientX - rect.left
const centerY = event.clientY - rect.top
drawAssistShape(centerX, centerY)
}
useImperativeHandle(ref, () => ({ updateAssistShape }))
return (
<canvas
ref={canvasRef}
style={{
backgroundColor: "transparent",
position: "absolute",
zIndex: 52,
pointerEvents: "none",
}}
/>
)
}
export default forwardRef(AssistShapeComponent)