import { canvasState, fontFamilyState, fontSizeState } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { fabric } from 'fabric' import { getDirectionByPoint } from '@/util/canvas-util' export const usePolygon = () => { const canvas = useRecoilValue(canvasState) const fontSize = useRecoilValue(fontSizeState) const fontFamily = useRecoilValue(fontFamilyState) const addPolygon = (points, options) => { const polygon = new fabric.Polygon(points, { ...options, selectable: options.selectable ?? false, }) canvas?.add(polygon) addLengthText(polygon) } const addPolygonByLines = (lines, options) => { const points = createPolygonPointsFromOuterLines(lines) addPolygon(points, { ...options, }) } const addLengthText = (polygon) => { const points = polygon.get('points') points.forEach((start, i) => { const end = points[(i + 1) % points.length] const dx = end.x - start.x const dy = end.y - start.y const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2) const degree = (Math.atan2(dy, dx) * 180) / Math.PI // Create new text object if it doesn't exist const text = new fabric.IText(length.toString(), { left: midPoint.x, top: midPoint.y, fontSize: fontSize, parentId: polygon.id, minX: Math.min(start.x, end.x), maxX: Math.max(start.x, end.x), minY: Math.min(start.y, end.y), maxY: Math.max(start.y, end.y), parentDirection: getDirectionByPoint(start, end), parentDegree: degree, dirty: true, editable: true, selectable: true, lockRotation: true, lockScalingX: true, lockScalingY: true, idx: i, name: 'lengthText', parent: this, }) // this.texts.push(text) canvas.add(text) }) canvas.renderAll() } const createPolygonPointsFromOuterLines = (outerLines) => { if (!outerLines || outerLines.length === 0) { return [] } // Extract points from outerLines return outerLines.map((line) => ({ x: line.x1, y: line.y1, })) } const removePolygon = (polygon) => { const texts = canvas.getObjects().filter((obj) => obj.parentId === polygon.id) texts.forEach((text) => { canvas.remove(text) }) canvas.remove(polygon) canvas.renderAll() } return { addPolygon, addPolygonByLines, removePolygon, } }