qcast-front/src/hooks/usePolygon.js

99 lines
2.5 KiB
JavaScript

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,
}
}