import { useRecoilValue } from 'recoil' import { canvasState, dotLineGridSettingState } from '@/store/canvasAtom' import { useEffect } from 'react' import { gridColorState } from '@/store/gridAtom' import { gridDisplaySelector } from '@/store/settingAtom' const GRID_PADDING = 5 export function useGrid() { const canvas = useRecoilValue(canvasState) const dotLineGridSetting = useRecoilValue(dotLineGridSettingState) const gridColor = useRecoilValue(gridColorState) const isGridDisplay = useRecoilValue(gridDisplaySelector) useEffect(() => { if (!canvas) { return } const patternData = { dotGridDisplay: dotLineGridSetting.DOT, lineGridDisplay: dotLineGridSetting.LINE, gridType: dotLineGridSetting.INTERVAL.type, gridHorizon: (dotLineGridSetting.INTERVAL.horizontalInterval / 10) * (dotLineGridSetting.INTERVAL.dimension ?? 1), gridVertical: (dotLineGridSetting.INTERVAL.verticalInterval / 10) * (dotLineGridSetting.INTERVAL.dimension ?? 1), gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, gridDimen: dotLineGridSetting.INTERVAL.dimension, } // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거 canvas ?.getObjects() .filter((obj) => ['lineGrid', 'dotGrid'].includes(obj.name)) .forEach((obj) => canvas?.remove(obj)) //const horizontalInterval = interval.horizontalInterval //const verticalInterval = interval.verticalInterval if (patternData.dotGridDisplay) { const circle = new fabric.Circle({ radius: 2, fill: 'red', strokeWidth: 0.7, originX: 'center', originY: 'center', selectable: false, lockMovementX: true, lockMovementY: true, lockRotation: true, lockScalingX: true, lockScalingY: true, }) const patternSourceCanvas = new fabric.StaticCanvas(null, { width: patternData.gridHorizon, height: patternData.gridVertical, }) patternSourceCanvas.add(circle) circle.set({ left: patternSourceCanvas.width / 2, top: patternSourceCanvas.height / 2, }) patternSourceCanvas.renderAll() const pattern = new fabric.Pattern({ source: patternSourceCanvas.getElement(), repeat: 'repeat', }) const backgroundPolygon = new fabric.Polygon( [ { x: -1500, y: -1500 }, { x: 2500, y: -1500 }, { x: 2500, y: 2500 }, { x: -1500, y: 2500 }, ], { fill: pattern, selectable: false, name: 'dotGrid', visible: isGridDisplay, }, ) canvas.add(backgroundPolygon) backgroundPolygon.sendToBack() canvas.renderAll() } if (patternData.lineGridDisplay) { for (let i = 0; i < 5000 / patternData.gridVertical + 1; i++) { const horizontalLine = new fabric.Line( [ -1500, -1500 + i * patternData.gridVertical - patternData.gridVertical / 2, 3000, -1500 + i * patternData.gridVertical - patternData.gridVertical / 2, ], { stroke: gridColor, strokeWidth: 1, selectable: true, lockMovementX: true, lockMovementY: true, lockRotation: true, lockScalingX: true, lockScalingY: true, name: 'lineGrid', strokeDashArray: [5, 2], opacity: 0.3, padding: GRID_PADDING, direction: 'horizontal', visible: isGridDisplay, }, ) canvas.add(horizontalLine) } for (let i = 0; i < 5000 / patternData.gridHorizon + 1; i++) { const verticalLine = new fabric.Line( [ -1500 + i * patternData.gridHorizon - patternData.gridHorizon / 2, -1500, -1500 + i * patternData.gridHorizon - patternData.gridHorizon / 2, 3000, ], { stroke: gridColor, strokeWidth: 1, selectable: true, lockMovementX: true, lockMovementY: true, lockRotation: true, lockScalingX: true, lockScalingY: true, name: 'lineGrid', strokeDashArray: [5, 2], opacity: 0.3, padding: GRID_PADDING, direction: 'vertical', visible: isGridDisplay, }, ) canvas.add(verticalLine) } } canvas.renderAll() }, [dotLineGridSetting]) const move = (object, x, y) => { object.set({ ...object, x1: object.direction === 'vertical' ? object.x1 + x : 0, x2: object.direction === 'vertical' ? object.x1 + x : canvas.width, y1: object.direction === 'vertical' ? 0 : object.y1 + y, y2: object.direction === 'vertical' ? canvas.height : object.y1 + y, }) } const copy = (object, length) => { const lineStartX = object.direction === 'vertical' ? object.x1 + length : 0 const lineEndX = object.direction === 'vertical' ? object.x2 + length : canvas.width const lineStartY = object.direction === 'vertical' ? 0 : object.y1 + length const lineEndY = object.direction === 'vertical' ? canvas.width : object.y1 + length const line = new fabric.Line([lineStartX, lineStartY, lineEndX, lineEndY], { stroke: gridColor, strokeWidth: 1, selectable: true, lockMovementX: true, lockMovementY: true, lockRotation: true, lockScalingX: true, lockScalingY: true, strokeDashArray: [5, 2], opacity: 0.3, padding: GRID_PADDING, direction: object.direction, visible: isGridDisplay, name: object.name, }) canvas.add(line) canvas.setActiveObject(line) canvas.renderAll() } const removeGrid = () => { canvas .getObjects() .filter((obj) => ['lineGrid', 'dotGrid', 'tempGrid'].includes(obj.name)) .forEach((obj) => canvas.remove(obj)) canvas.renderAll() } return { move, copy, removeGrid, } }