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, gridVertical: dotLineGridSetting.INTERVAL.verticalInterval / 10, gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, gridDimen: dotLineGridSetting.INTERVAL.dimension, } // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거 canvas ?.getObjects() .filter((obj) => obj.name === 'lineGrid') .forEach((obj) => canvas?.remove(obj)) canvas ?.getObjects() .filter((obj) => obj.name === 'dotGrid') .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: 0, y: 0 }, { x: canvas.width, y: 0 }, { x: canvas.width, y: canvas.height }, { x: 0, y: canvas.height }, ], { fill: pattern, selectable: false, name: 'dotGrid', visible: isGridDisplay, }, ) canvas.add(backgroundPolygon) backgroundPolygon.sendToBack() canvas.renderAll() } if (patternData.lineGridDisplay) { for (let i = 0; i < canvas.height / patternData.gridVertical + 1; i++) { const horizontalLine = new fabric.Line( [0, i * patternData.gridVertical - patternData.gridVertical / 2, canvas.width, 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 < canvas.width / patternData.gridHorizon + 1; i++) { const verticalLine = new fabric.Line( [i * patternData.gridHorizon - patternData.gridHorizon / 2, 0, i * patternData.gridHorizon - patternData.gridHorizon / 2, canvas.height], { 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() } return { move, copy, } }