diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index a44abb81..c5bd5686 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useRef } from 'react' +import { useCallback, useEffect, useRef } from 'react' import WithDraggable from '@/components/common/draggable/withDraggable' import { modalState } from '@/store/modalAtom' import { useRecoilState, useRecoilValue } from 'recoil' @@ -22,7 +22,7 @@ import { useLine } from '@/hooks/useLine' export default function OuterLineWall() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state const { getMessage } = useMessage() - const { addCanvasMouseEventListener, addDocumentEventListener } = useEvent() + const { addCanvasMouseEventListener, addDocumentEventListener, removeAllDocumentEventListeners } = useEvent() const { addLineText, removeLineText } = useLine() const length1Ref = useRef(null) const length2Ref = useRef(null) @@ -32,21 +32,35 @@ export default function OuterLineWall() { const [arrow2, setArrow2] = useRecoilState(outerLineArrow2State) const [points, setPoints] = useRecoilState(outerLinePointsState) const [type, setType] = useRecoilState(outerLineTypeState) + const arrow1Ref = useRef(arrow1) + const arrow2Ref = useRef(arrow2) const canvas = useRecoilValue(canvasState) useEffect(() => { addCanvasMouseEventListener('mouse:down', mouseDown) - addDocumentEventListener('keydown', document, keydown) }, []) useEffect(() => { + arrow1Ref.current = arrow1 + }, [arrow1]) + + useEffect(() => { + arrow2Ref.current = arrow2 + }, [arrow2]) + + useEffect(() => { + removeAllDocumentEventListeners() + addDocumentEventListener('keydown', document, keydown[type]) clear() }, [type]) const clear = () => { setLength1(0) + setLength2(0) + setArrow1('') + setArrow2('') } const mouseDown = (e) => { @@ -102,55 +116,206 @@ export default function OuterLineWall() { addLineText(line) } - const keydown = (e) => { - const key = e.key + // 직각 완료될 경우 확인 + const checkRightAngle = () => { + const length1Num = Number(length1Ref.current.value) / 10 + const length2Num = Number(length2Ref.current.value) / 10 + console.log(length1Num, length2Num, arrow1Ref.current, arrow2Ref.current) - const lengthNum = Number(length1Ref.current.value) / 10 - if (lengthNum === 0) { + if (points.length === 0) { return } - switch (key) { - case 'Down': // IE/Edge에서 사용되는 값 - case 'ArrowDown': - setArrow1('↓') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y + lengthNum }] - }) - break - case 'Up': // IE/Edge에서 사용되는 값 - case 'ArrowUp': - setArrow1('↑') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y - lengthNum }] - }) - break - case 'Left': // IE/Edge에서 사용되는 값 - case 'ArrowLeft': - setArrow1('←') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x - lengthNum, y: prev[prev.length - 1].y }] - }) - break - case 'Right': // IE/Edge에서 사용되는 값 - case 'ArrowRight': - setArrow1('→') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x + lengthNum, y: prev[prev.length - 1].y }] - }) - break + + if (length1Num === 0 || length2Num === 0 || arrow1Ref.current === '' || arrow2Ref.current === '') { + return } + + if (arrow1Ref.current === '↓' && arrow2Ref.current === '→') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length2Num, y: prev[prev.length - 1].y + length1Num }] + }) + } else if (arrow1Ref.current === '↓' && arrow2Ref.current === '←') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length2Num, y: prev[prev.length - 1].y + length1Num }] + }) + } else if (arrow1Ref.current === '↑' && arrow2Ref.current === '→') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length2Num, y: prev[prev.length - 1].y - length1Num }] + }) + } else if (arrow1Ref.current === '↑' && arrow2Ref.current === '←') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length2Num, y: prev[prev.length - 1].y - length1Num }] + }) + } else if (arrow1Ref.current === '→' && arrow2Ref.current === '↓') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length1Num, y: prev[prev.length - 1].y + length2Num }] + }) + } else if (arrow1Ref.current === '→' && arrow2Ref.current === '↑') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length1Num, y: prev[prev.length - 1].y - length2Num }] + }) + } else if (arrow1Ref.current === '←' && arrow2Ref.current === '↓') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length1Num, y: prev[prev.length - 1].y + length2Num }] + }) + } else if (arrow1Ref.current === '←' && arrow2Ref.current === '↑') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length1Num, y: prev[prev.length - 1].y - length2Num }] + }) + } + } + + const keydown = { + outerLine: (e) => { + const key = e.key + + if (!length1Ref.current) { + return + } + + const lengthNum = Number(length1Ref.current.value) / 10 + if (lengthNum === 0) { + return + } + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + setArrow1('↓') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y + lengthNum }] + }) + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + setArrow1('↑') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y - lengthNum }] + }) + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + setArrow1('←') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - lengthNum, y: prev[prev.length - 1].y }] + }) + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + setArrow1('→') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + lengthNum, y: prev[prev.length - 1].y }] + }) + break + } + }, + rightAngle: (e) => { + const key = e.key + + const activeElem = document.activeElement + const length1Num = Number(length1Ref.current.value) / 10 + const length2Num = Number(length2Ref.current.value) / 10 + + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + if (activeElem === length1Ref.current) { + setArrow1('↓') + arrow1Ref.current = '↓' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { + break + } + setArrow2('↓') + arrow2Ref.current = '↓' + checkRightAngle() + } + + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + if (activeElem === length1Ref.current) { + setArrow1('↑') + arrow1Ref.current = '↑' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { + break + } + setArrow2('↑') + arrow2Ref.current = '↑' + checkRightAngle() + } + + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + if (activeElem === length1Ref.current) { + setArrow1('←') + arrow1Ref.current = '←' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { + break + } + setArrow2('←') + arrow2Ref.current = '←' + checkRightAngle() + } + + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + if (activeElem === length1Ref.current) { + setArrow1('→') + arrow1Ref.current = '→' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { + break + } + setArrow2('→') + arrow2Ref.current = '→' + checkRightAngle() + } + + break + } + }, } /** @@ -228,6 +393,43 @@ export default function OuterLineWall() { + ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( +