From 9199accb24e175320a48d7f96e10a90e6d24f7df Mon Sep 17 00:00:00 2001 From: minsik Date: Thu, 28 Nov 2024 14:05:26 +0900 Subject: [PATCH] =?UTF-8?q?-=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20padding=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99,=20=EB=B3=B5=EC=82=AC,=20=EC=82=AD=EC=A0=9C,?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/grid/GridCopy.jsx | 50 +++++++- .../floor-plan/modal/grid/GridMove.jsx | 120 ++++++++++++++++-- src/hooks/common/useGrid.js | 47 ++++++- src/hooks/useContextMenu.js | 14 +- src/hooks/useTempGrid.js | 3 + 5 files changed, 214 insertions(+), 20 deletions(-) diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index 0f2bfc22..86f79df7 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -3,13 +3,23 @@ import { useMessage } from '@/hooks/useMessage' import { usePopup } from '@/hooks/usePopup' import { useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' +import { useState } from 'react' +import { currentObjectState } from '@/store/canvasAtom' +import { useGrid } from '@/hooks/common/useGrid' export default function GridCopy(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition } = props const { getMessage } = useMessage() const { closePopup } = usePopup() - + const [length, setLength] = useState('0') + const [arrow, setArrow] = useState(null) + const currentObject = useRecoilValue(currentObjectState) + const { copy } = useGrid() + const handleApply = () => { + // copy(currentObject, ) + copy(currentObject, ['↑', '←'].includes(arrow) ? Number(length) * -1 : Number(length)) + } return (
@@ -26,20 +36,46 @@ export default function GridCopy(props) {
{getMessage('modal.grid.copy.length')}
- + setLength(e.target.value)} />
mm
- - - - + + + +
- +
diff --git a/src/components/floor-plan/modal/grid/GridMove.jsx b/src/components/floor-plan/modal/grid/GridMove.jsx index 7b39c3f6..f853f135 100644 --- a/src/components/floor-plan/modal/grid/GridMove.jsx +++ b/src/components/floor-plan/modal/grid/GridMove.jsx @@ -1,21 +1,83 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import { useMessage } from '@/hooks/useMessage' import { usePopup } from '@/hooks/usePopup' -import { useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' +import { useCanvas } from '@/hooks/useCanvas' +import { canvasState, currentObjectState } from '@/store/canvasAtom' +import { useEffect, useState } from 'react' +import { useGrid } from '@/hooks/common/useGrid' +import { useSwal } from '@/hooks/useSwal' +import { set } from 'react-hook-form' export default function GridMove(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition } = props + const canvas = useRecoilValue(canvasState) const { getMessage } = useMessage() const { closePopup } = usePopup() + const { swalFire } = useSwal() + const { move } = useGrid() + const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) + const [isAll, setIsAll] = useState(false) + const [verticalSize, setVerticalSize] = useState('0') + const [horizonSize, setHorizonSize] = useState('0') + const [arrow1, setArrow1] = useState(null) + const [arrow2, setArrow2] = useState(null) + useEffect(() => { + if (currentObject?.direction === 'vertical') { + setArrow1(null) + setVerticalSize('0') + } else { + setArrow2(null) + setHorizonSize('0') + } + }, [currentObject]) + + const handleApply = () => { + if (currentObject?.direction === 'vertical') { + if (!horizonSize || !arrow2) { + swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + return + } + } else { + if (!verticalSize || !arrow1) { + swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + } + } + + if (isAll) { + canvas + .getObjects() + .filter((obj) => ['lineGrid', 'tempGrid', 'dotGrid'].includes(obj.name)) + .forEach((grid) => { + move( + grid, + arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize), + arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize), + ) + }) + } else { + move( + currentObject, + arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize), + arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize), + ) + } + canvas.renderAll() + handleClose() + } + + const handleClose = () => { + closePopup(id) + } return (

{getMessage('modal.grid.move')}

-
@@ -23,7 +85,7 @@ export default function GridMove(props) {
{getMessage('modal.grid.move.info')}
- + setIsAll(!isAll)} />
@@ -31,29 +93,67 @@ export default function GridMove(props) {

{getMessage('modal.grid.move.length')}

- + setVerticalSize(e.target.value)} + readOnly={!isAll && currentObject?.direction === 'vertical'} + />
mm
- - + +
- + setHorizonSize(e.target.value)} + readOnly={!isAll && currentObject?.direction === 'horizontal'} + />
mm
- - + +
- +
diff --git a/src/hooks/common/useGrid.js b/src/hooks/common/useGrid.js index 0c6159dd..5565ef54 100644 --- a/src/hooks/common/useGrid.js +++ b/src/hooks/common/useGrid.js @@ -3,7 +3,7 @@ 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) @@ -108,6 +108,7 @@ export function useGrid() { name: 'lineGrid', strokeDashArray: [5, 2], opacity: 0.3, + padding: GRID_PADDING, direction: 'horizontal', visible: isGridDisplay, }, @@ -130,6 +131,7 @@ export function useGrid() { name: 'lineGrid', strokeDashArray: [5, 2], opacity: 0.3, + padding: GRID_PADDING, direction: 'vertical', visible: isGridDisplay, }, @@ -141,5 +143,46 @@ export function useGrid() { canvas.renderAll() }, [dotLineGridSetting]) - return {} + 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, + } } diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index f7f79f23..cbf326e8 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -521,11 +521,23 @@ export function useContextMenu() { { id: 'remove', name: getMessage('contextmenu.remove'), + fn: () => { + canvas.remove(currentObject) + canvas.discardActiveObject() + }, }, { id: 'removeAll', name: getMessage('contextmenu.remove.all'), - fn: () => {}, + fn: () => { + canvas + .getObjects() + .filter((obj) => ['tempGrid', 'lineGrid', 'dotGrid'].includes(obj.name)) + .forEach((grid) => { + canvas.remove(grid) + }) + canvas.discardActiveObject() + }, }, ], ]) diff --git a/src/hooks/useTempGrid.js b/src/hooks/useTempGrid.js index 30847a2f..7bfcf263 100644 --- a/src/hooks/useTempGrid.js +++ b/src/hooks/useTempGrid.js @@ -3,6 +3,7 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { gridColorState } from '@/store/gridAtom' import { gridDisplaySelector } from '@/store/settingAtom' +const GRID_PADDING = 5 export function useTempGrid() { const canvas = useRecoilValue(canvasState) const gridColor = useRecoilValue(gridColorState) @@ -23,6 +24,7 @@ export function useTempGrid() { lockScalingY: true, strokeDashArray: [5, 2], opacity: 0.3, + padding: GRID_PADDING, direction: 'vertical', visible: isGridDisplay, name: 'tempGrid', @@ -50,6 +52,7 @@ export function useTempGrid() { lockScalingY: true, strokeDashArray: [5, 2], opacity: 0.3, + padding: GRID_PADDING, name: 'tempGrid', visible: isGridDisplay, direction: 'horizontal',